क्या मैं आज तक MongoDB ObjectId को क्वेरी कर सकता हूं?


145

मुझे पता है कि ObjectIds में वे तारीख थी जो उन्होंने बनाई थी। क्या ObjectId के इस पहलू को क्वेरी करने का कोई तरीका है?



मैंने अपना समाधान steveridout.github.io/mongo-object-time
bpedroso

जवाबों:


224

ObjectIds में टाइमस्टैम्प्स को रोकना ObjectId में एम्बेडेड तारीखों के आधार पर प्रश्नों को बहुत विस्तार से कवर करता है।

संक्षेप में जावास्क्रिप्ट कोड में:

/* 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') } });

29
बहुत ही आसान .. FYI करें, आप इस फ़ंक्शन को अपनी ~/.mongorc.jsफ़ाइल में सहेज सकते हैं जब mongoशेल शुरू होता है।
स्टेनी

1
मुझे संदर्भ प्राप्त होता है: ObjectId परिभाषित नहीं है। मुझसे इसका समाधान किस प्रकार होगा?
पीर

3
मैं mongodbnative के साथ नोडज का उपयोग कर रहा हूं। Var ObjectId = आवश्यकता ('mongodb') को शामिल करके "परिभाषित नहीं की गई त्रुटि" को ठीक किया।
याचिकाकर्ता

1
यदि आप Mongoskin का उपयोग कर रहे हैं जैसे मैं करता हूं: Change ObjectId(hexSeconds + "0000000000000000");todb.ObjectID.createFromHexString(hexSeconds + "0000000000000000");
Anders Decstman

2
या, Mongoose में, इसके ObjectId()साथ बदलें : require('mongoose').Types.ObjectId()- जहाँ require('mongoose')आपका आरंभिक / कॉन्फ़िगर किया गया Mongoose उदाहरण है।
टोबलरप्वेन

34

Node.js में मोंगोडब ड्राइवरों द्वारा प्रदान की गई इनबिल्ट फ़ंक्शन का उपयोग करना आपको किसी भी टाइमस्टैम्प द्वारा क्वेरी करने देता है:

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

वैकल्पिक रूप से, वर्तमान समय से पहले रिकॉर्ड की खोज करने के लिए, आप बस कर सकते हैं:

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

स्रोत: http://mongodb.github.io/node-mongodb-native/api-bson-generated/objectid.html


3
यह एक जावास्क्रिप्ट एनवी में टाइमस्टैम्प से ऑब्जेक्टआईड बनाने का सबसे अच्छा / सबसे आसान तरीका है। कौन सा ऑप पूछता है ...
एंडर्स Janstman

34

में pymongo, यह इस तरह से किया जा सकता है:

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}}))

Datetime.datetime.utcnow () या datetime.datetime.today () का उपयोग करके नोट वही परिणाम लौटाएगा। डेटाटाइम आपके लिए संभाला जाता है।
रेडटेक

वैकल्पिक रूप से, pymongoनिर्भरता का उपयोग किए बिना : epoch_time_hex = format(int(time.time()), 'x') (अपनी क्वेरी के लिए शून्य जोड़ना न भूलें) समय पैकेज का उपयोग किया गया था ( import time)।
VasiliNovikov

पता चलता है कि ओपी जावास्क्रिप्ट के लिए पूछ रहा था, लेकिन इससे मुझे अपने कोड को सरल बनाने में मदद मिली। धन्यवाद।
फ्रेड एस

14

चूंकि ObjectId के पहले 4 बाइट्स आपके संग्रह को कालानुक्रमिक रूप से क्वेरी करने के लिए टाइमस्टैम्प का प्रतिनिधित्व करते हैं , बस आईडी द्वारा ऑर्डर करें:

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

दस्तावेज़ प्राप्त करने के बाद, आप ObjectId की पीढ़ी का समय इस तरह प्राप्त कर सकते हैं :

id = some_object_id
generation_time = id.generation_time

1
मैं किसी ऐसी चीज की उम्मीद कर रहा था जो वास्तव में चीजों को करने की अनुमति देती है जैसे ऑब्जेक्ट को निश्चित समय में उपयोग करने से पहले बनाई गई वस्तुओं की एक गिनती मिलती है, लेकिन ऐसा लगता है कि यह सीधे सुलभ नहीं होगा। धन्यवाद।
जाच

1
आप ऐसा कर सकते हैं, वामपंथी का जवाब देखिए।
एटीपी

13

इस दिनांक [2015-1-15] को कमांड (इस तिथि [2015-1-12]] को कैसे खोजें:

db.collection.find ({_ id: {$ gt: ObjectId (Math.floor ((नई तिथि (2015/1/12))) / 1000) .toString (16) + "0000000000000000"), $ lt: ObjectId। (Math.floor ((नई तिथि ('2015/1/15')) / 1000) .toString (16) + "0000000000000000")}})। सुंदर ()

कमांड की गणना (इस तिथि [2015-1-12] को इस तिथि [2015-1-15]):

db.collection.count ({_ id: {$ gt: ObjectId (Math.floor ((नई तिथि (2015/1/12))) / 1000) .toString (16) + "0000000000000000"), $ lt: ObjectId। (Math.floor ((नई तिथि ('2015/1/15')) / 1000) .toString (16) + "0000000000000000")}})

कमांड (इस तारीख [2015-1-12] को इस तारीख [2015-1-15]) को हटा दें:

db.collection.remove ({_ id: {$ gt: ObjectId (Math.floor ((नई तिथि (2015/1/12))) / 1000) .toString (16) + "0000000000000000"), $ lt: ObjectId। (Math.floor ((नई तिथि ('2015/1/15')) / 1000) .toString (16) + "0000000000000000")}})


10

आप $convert4.0 संस्करण में शुरू होने वाले ऑब्जेक्टआईड से तारीख निकालने के लिए फ़ंक्शन का उपयोग कर सकते हैं ।

कुछ इस तरह

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

आप दिनांक के लिए प्रारंभ और समाप्ति समय के बीच तुलना कर सकते हैं।

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")]}
    ]
  }
})

या

आप इसे $toDateप्राप्त करने के लिए आशुलिपि का उपयोग कर सकते हैं ।

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")]}
    ]
  }
})

बस $ कन्वर्ट या $ टॉड का उपयोग करने के रूप में पूछना चाहता था, मोंगो को पहले कन्वर्ट करना होगा और फिर तुलना करनी होगी कि क्या डॉक्टर रेंज में मौजूद है या नहीं, लेकिन अगर मैं स्वीकृत उत्तर के दृष्टिकोण का उपयोग करूंगा तो मुझे एक ऑब्जेक्टआईड में तारीख परिवर्तित करना होगा। ग्राहक की ओर और केवल एक बार, तो क्या आपको नहीं लगता कि समाधान इससे अधिक कुशल होगा? वैसे भी यह बताने के लिए धन्यवाद कि ये दोनों संचालक भी मौजूद हैं :)
सुधांशु गौर

7

पिछले 60 दिनों के पुराने दस्तावेज़ों को प्राप्त करने के लिए मैंगो संग्रह में शेल में क्वेरी के नीचे इस्तेमाल किया गया था।

db.collection.find({_id: {$lt:new ObjectId( Math.floor(new Date(new Date()-1000*60*60*24*60).getTime()/1000).toString(16) + "0000000000000000" )}})

1
$ Lt के बजाय $ gt का उपयोग करें। अन्यथा, यह पहले (आज -60 दिन) पहले डाले गए दस्तावेज़ों को ढूंढता है।
योशि

1
@Vivek ObjectId के पहले 4 बाइट्स यूनिक्स एपोच (1970/1/1 00:00:00 UTC) के बाद से सेकंड की संख्या का प्रतिनिधित्व करते हैं, और जैसे कि आप इसे ($ gt) से अधिक और $ ($ से कम) के साथ उपयोग कर सकते हैं lt) उन वस्तुओं को खोजने के लिए जिन्हें एक निश्चित विंडो के भीतर बनाया गया था।
जॉन

5

यदि आप एक श्रेणी क्वेरी बनाना चाहते हैं, तो आप इसे इस पोस्ट की तरह कर सकते हैं । उदाहरण के लिए किसी विशिष्ट दिन के लिए क्वेरी करना (अर्थात अप्रैल 2015):

> var objIdMin = ObjectId(Math.floor((new Date('2015/4/4'))/1000).toString(16) + "0000000000000000")
> var objIdMax = ObjectId(Math.floor((new Date('2015/4/5'))/1000).toString(16) + "0000000000000000")
> db.collection.find({_id:{$gt: objIdMin, $lt: objIdMax}}).pretty()


2

MongoObjectID का उपयोग करते हुए आपको नीचे दिए गए परिणाम भी प्राप्त करने चाहिए

db.mycollection.find({ _id: { $gt: ObjectId("5217a543dd99a6d9e0f74702").getTimestamp().getTime()}});

3
आपका क्वेरी स्टेटमेंट मान लेता है कि किसी को ऑब्जेक्टआईड वैल्यू पता है जिसकी शुरुआत हमेशा नहीं होती है।
ड्वाइट स्पेंसर

0

रेल में mongoidआप उपयोग करके क्वेरी कर सकते हैं

  time = Time.utc(2010, 1, 1)
  time_id = ObjectId.from_time(time)
  collection.find({'_id' => {'$lt' => time_id}})
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.