javascript - Pot să interoghez MongoDB ObjectId după dată?


Știu că ObjectId-urile conțin data la care au fost create. Există o modalitate de a interoga acest aspect al ObjectId-ului?

Răspuns #1

Introducerea de timpi în ObjectId-uri acoperă în detaliu interogările bazate pe datele încorporate în ObjectId.

Pe scurt în cod JavaScript:

/* This function returns an ObjectId embedded with a given datetime */
/* Accepts both Date object and string input */

function objectIdWithTimestamp(timestamp) {
    /* Convert string date to Date object (otherwise assume timestamp is a date) */
    if (typeof(timestamp) == 'string') {
        timestamp = new Date(timestamp);
    }

    /* Convert date object to hex seconds since Unix epoch */
    var hexSeconds = Math.floor(timestamp/1000).toString(16);

    /* Create an ObjectId with that hex timestamp */
    var constructedObjectId = ObjectId(hexSeconds + "0000000000000000");

    return constructedObjectId
}


/* Find all documents created after midnight on May 25th, 1980 */
db.mycollection.find({ _id: { $gt: objectIdWithTimestamp('1980/05/25') } });

Răspunsul #2

În pymongo, se poate face astfel:

import datetime
from bson.objectid import ObjectId
mins = 15
gen_time = datetime.datetime.today() - datetime.timedelta(mins=mins) 
dummy_id = ObjectId.from_datetime(gen_time)
result = list(db.coll.find({"_id": {"$gte": dummy_id}}))

Răspunsul #3

Folosind funcția încorporată oferită de driverele MongoDB în Node.js îți permite să interoghezi după orice timestamp:

var timestamp = Date.now();
var objectId = ObjectID.createFromTime(timestamp / 1000);

Alternativ, pentru a căuta înregistrări înainte de timpul curent, poți pur și simplu să faci:

var objectId = new ObjectID(); // or ObjectId in the mongo shell

Sursă: http://mongodb.github.io/node-mongodb-native/api-bson-generated/objectid.html

Răspunsul #4

Poți folosi funcția $convert pentru a extrage data din ObjectId începând cu versiunea 4.0.

Ceva de genul

$convert: { input: "$_id", to: "date" } 

Poți interoga pe baza datei comparând între timpul de început și sfârșit pentru dată.

db.collectionname.find({
  "$expr":{
    "$and":[
      {"$gte":[{"$convert":{"input":"$_id","to":"date"}}, ISODate("2018-07-03T00:00:00.000Z")]},
      {"$lte":[{"$convert":{"input":"$_id","to":"date"}}, ISODate("2018-07-03T11:59:59.999Z")]}
    ]
  }
})

SAU

Poți folosi prescurtarea $toDate pentru a obține același lucru.

db.collectionname.find({
  "$expr":{
    "$and":[
      {"$gte":[{"$toDate":"$_id"}, ISODate("2018-07-03T00:00:00.000Z")]},
      {"$lte":[{"$toDate":"$_id"},ISODate("2018-07-03T11:59:59.999Z")]}
    ]
  }
})

Răspunsul #5

cum să găsiți Găsiți Comanda (această date[2015-1-12] până la această Date[2015-1-15]):

db.collection.find({
  _id: {
    $gt: ObjectId(Math.floor((new Date('2015/1/12'))/1000).toString(16) + "0000000000000000"), 
    $lt: ObjectId(Math.floor((new Date('2015/1/15'))/1000).toString(16) + "0000000000000000")
  }
}).pretty()

Numărați comanda (această date[2015-1-12] până la această Date[2015-1-15]):

db.collection.count({
  _id: {
    $gt: ObjectId(Math.floor((new Date('2015/1/12'))/1000).toString(16) + "0000000000000000"), 
    $lt: ObjectId(Math.floor((new Date('2015/1/15'))/1000).toString(16) + "0000000000000000")
  }
})

Eliminați comanda (de la date[2015-1-12] la Date[2015-1-15]):

db.collection.remove({
  _id: {
    $gt: ObjectId(Math.floor((new Date('2015/1/12'))/1000).toString(16) + "0000000000000000"), 
    $lt: ObjectId(Math.floor((new Date('2015/1/15'))/1000).toString(16) + "0000000000000000")
  }
})

Răspunsul #6

Deoarece primele 4 octeți ai unui ObjectId reprezintă un timestamp, pentru a interoga colecția ta în ordine cronologică, pur și simplu ordonează după id:

oldest first; use pymongo.DESCENDING for most recent first
items = db.your_collection.find().sort("_id", pymongo.ASCENDING)

După ce obții documentele, poți obține timpul de generare al ObjectId astfel:

id = some_object_id
generation_time = id.generation_time

Răspunsul #7

Da, poți interoga obiecte după dată folosind ID-ul inserat în MongoDB

db.collectionname.find({_id: {$lt: ObjectId.fromDate( new ISODate("TZformat") ) } });

să presupunem că users este colecția mea și vreau toți utilizatorii creați înainte de 05 ianuarie 2018

db.users.find({_id: {$lt: ObjectId.fromDate( new ISODate("2018-01-05T00:00:00.000Z") ) } });

Pentru rularea unui query putem folosi like

db.users.find({_id: {$lt: ObjectId.fromDate(new Date((new Date().getTime() - (1 * 3 * 60 * 60 * 1000))) ) } })

Toți utilizatorii din intervalul de timp curent - 3 ore