मोंगोडब में अंतिम एन रिकॉर्ड कैसे प्राप्त करें?


523

मुझे यह कहीं भी नहीं मिल रहा है कि यह इसे प्रलेखित किया गया है। डिफ़ॉल्ट रूप से, खोज () ऑपरेशन शुरू से रिकॉर्ड प्राप्त करेगा। मैं मोंगोडब में अंतिम एन रिकॉर्ड कैसे प्राप्त कर सकता हूं?

संपादित करें: मैं यह भी चाहता हूं कि लौटे हुए परिणाम को हाल ही में सबसे हाल ही में आदेश दिया गया है, न कि रिवर्स।


7
@ हईम, उत्तर के लिए विशिष्ट होना चाहिए, वेब पेज का कौन सा हिस्सा मेरे प्रश्न का समाधान करता है?
बिन चेन

हाय @BinChen, मैं हाल ही में एक ही समस्या है, यह हल है?
हैटन

जवाबों:


736

अगर मुझे आपका सवाल समझ में आता है, तो आपको आरोही क्रम में क्रमबद्ध करना होगा।

मान लें कि आपके पास "x" नामक कुछ आईडी या दिनांक फ़ील्ड है, तो आप ऐसा करेंगे ...

.sort ()


db.foo.find().sort({x:1});

1 क्रम में क्रमबद्ध करेगा (नवीनतम करने के लिए सबसे पुराना) और -1 तरह उतरते जाएगा (सबसे पुराना करने के लिए नवीनतम।)

यदि आप स्वतः निर्मित _id फ़ील्ड का उपयोग करते हैं, तो उसमें एक दिनांक अंतर्निहित है ... इसलिए आप इसका उपयोग करके ऑर्डर कर सकते हैं ...

db.foo.find().sort({_id:1});

यह आपके पुराने सभी दस्तावेजों को सबसे पुराने से नवीनतम में वापस लौटा देगा।

स्वाभाविक विधान


आप ऊपर बताए गए प्राकृतिक आदेश का भी उपयोग कर सकते हैं ...

db.foo.find().sort({$natural:1});

फिर से, 1 या -1 का उपयोग करके आप जो ऑर्डर चाहते हैं, उसके आधार पर।

.Limit का उपयोग करें ()


अंत में, इस तरह की चौड़ी खुली क्वेरी करते समय एक सीमा जोड़ना अच्छा होता है ताकि आप या तो कर सकें ...

db.foo.find().sort({_id:1}).limit(50);

या

db.foo.find().sort({$natural:1}).limit(50);

11
@MortezaM। मुझे पूरा यकीन है कि आपने अपने क्वेरी ऑर्डर को मिला दिया है ... आपके सॉर्ट () को अंतिम रूप से चलाया जाना चाहिए, न कि पहले (SQL ORER
जस्टिन जेनकिंस

6
कभी भी ऐसा होता है, कॉलिंग फंक्शंस के ऑर्डर का अंतिम परिणाम से कोई लेना-देना नहीं है।
मोर्टेजा मिलानी

7
@MortezaM। बेशक आदेश मायने रखता है। item = 3; item.add(3).divide(3) == 2; item.divide(3).add(3) == 4;बिना किसी आदेश के परिणाम क्या होगा ??? मैं आपसे सहमत हूं कि यह उलटा क्रम सहज नहीं है। यह कोई SQL नहीं है क्योंकि इसे सामान्य OO प्रतिमानों का पालन करना चाहिए।
रिका

37
और अभी तक आदेश आदेश नहीं है। आपको बस यह देखने की कोशिश करनी है कि यह नहीं होता है। इन सभी को कर्सर पर बुलाया जाता है और सर्वर पर भेज दिया जाता है ताकि सर्वर सॉर्ट (टॉप एन) के परिणामों को सीमित कर दे क्योंकि कुछ और मतलब नहीं होगा।
अस्य कामस्की

9
डॉक्स पुष्टि करते हैं कि आदेश कोई फर्क नहीं पड़ता: लिंक
जॉनीएचके

120

पिछले एन जोड़ा रिकॉर्ड, कम से कम हाल ही में सबसे हाल ही में, इस क्वेरी के साथ देखा जा सकता है:

db.collection.find().skip(db.collection.count() - N)

यदि आप उन्हें उल्टे क्रम में चाहते हैं:

db.collection.find().sort({ $natural: -1 }).limit(N)

यदि आप Mongo- हैकर स्थापित करते हैं तो आप इसका उपयोग भी कर सकते हैं:

db.collection.find().reverse().limit(N)

यदि आप हर समय इन कमांड को लिखने में थक जाते हैं, तो आप अपने ~ / .mongorc.js में कस्टम फ़ंक्शन बना सकते हैं। उदाहरण के लिए

function last(N) {
    return db.collection.find().skip(db.collection.count() - N);
}

फिर एक प्रकार का पौधा खोल से last(N)


1
db.collection.find().reverse().limit(1)मुझे त्रुटि देता है... has no method reverse
कैटफिश

@ कैटफ़िश आप सही हैं, मैंने अभी देखा कि रिवर्स () [मोंगो-हैकर] ( tylerbrock.github.com/mongo-hacker ) द्वारा जोड़ा गया था , मैं अपना जवाब अपडेट करूंगा। धन्यवाद।
ट्रासपलाजियो गार्जुग्लियो

1
db.getCollection ('COLLECTION_NAME')। ढूँढें ()। स्किप (db.getCollection ('COLLECTION_NAME'))। काउंट () - N) मेरे लिए बहुत अच्छा काम कर रहा है :)
Spl2stky

यह सवाल का जवाब होना चाहिए, न कि जस्टिन जेनकिंस का जवाब।
Jadiel de Armas

प्राकृतिक आदेश पर भरोसा नहीं किया जाना चाहिए ; यदि आप एक प्रतिकृति सेट का उपयोग कर रहे हैं (और आपको होना चाहिए), विभिन्न नोड्स में डिस्क पर एक अलग क्रम में संग्रहीत एक ही दस्तावेज़ हो सकते हैं।
विंस बॉड्रेन

14

अंतिम एन रिकॉर्ड प्राप्त करने के लिए आप क्वेरी के नीचे निष्पादित कर सकते हैं:

db.yourcollectionname.find({$query: {}, $orderby: {$natural : -1}}).limit(yournumber)

अगर आप केवल एक आखिरी रिकॉर्ड चाहते हैं:

db.yourcollectionname.findOne({$query: {}, $orderby: {$natural : -1}})

नोट: $ प्राकृतिक के स्थान पर आप अपने संग्रह में से किसी एक स्तंभ का उपयोग कर सकते हैं।


यह मेरे लिए काम करता है db.yourcollectionname.findOne ({$ क्वेरी: {}, $ आदेश: {$ प्राकृतिक: -1}})। मुझे लगता है कि अंतिम पैराथेंसिस जवाब में गायब है
अजय

प्राकृतिक आदेश पर भरोसा नहीं किया जाना चाहिए ; यदि आप एक प्रतिकृति सेट का उपयोग कर रहे हैं (और आपको होना चाहिए), विभिन्न नोड्स में डिस्क पर एक अलग क्रम में संग्रहीत एक ही दस्तावेज़ हो सकते हैं।
विंस बॉड्रेन

6

आप उपयोग कर सकते हैं sort(), limit(), skip()किसी भी छोड़ दिया मूल्य से पिछले एन रिकॉर्ड प्रारंभ करने के लिए

db.collections.find().sort(key:value).limit(int value).skip(some int value);

6

आप इस विधि को आजमा सकते हैं:

के साथ संग्रह में रिकॉर्ड की कुल संख्या प्राप्त करें

db.dbcollection.count() 

फिर स्किप का उपयोग करें:

db.dbcollection.find().skip(db.dbcollection.count() - 1).pretty()

5

क्वेरी के अंतर्गत देखें: सॉर्टिंग और प्राकृतिक आदेश, http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order साथ ही साथ () कर्सर विधि के तहत http://www.mongodb.org/display / डॉक्स / उन्नत + प्रश्नों


1
आपके awser के लिए धन्यवाद, यह करीब है, लेकिन मैं कम से कम हाल के सबसे हाल ही में रिकॉर्ड किए गए रिकॉर्ड को वापस लेना चाहता हूं, क्या यह संभव है?
बिन चेन

प्राकृतिक आदेश पर भरोसा नहीं किया जाना चाहिए ; यदि आप एक प्रतिकृति सेट का उपयोग कर रहे हैं (और आपको होना चाहिए), विभिन्न नोड्स में डिस्क पर एक अलग क्रम में संग्रहीत एक ही दस्तावेज़ हो सकते हैं।
विंस बॉड्रेन

यदि आप सबसे हालिया रिकॉर्ड प्राप्त करना चाहते हैं, तो आपको दस्तावेज़ में दिनांक फ़ील्ड पर निर्भर रहना होगा।
विंस बॉड्रेन

5

आप संग्रह के आकार के आधार पर "स्किप" नहीं कर सकते, क्योंकि यह क्वेरी स्थितियों को ध्यान में नहीं रखेगा।

सही समाधान वांछित अंत-बिंदु से सॉर्ट करने के लिए है, परिणाम सेट के आकार को सीमित करें, फिर यदि आवश्यक हो तो परिणामों के क्रम को समायोजित करें।

यहां एक उदाहरण है, जो वास्तविक-विश्व कोड पर आधारित है।

var query = collection.find( { conditions } ).sort({$natural : -1}).limit(N);

query.exec(function(err, results) {
    if (err) { 
    }
    else if (results.length == 0) {
    }
    else {
        results.reverse(); // put the results into the desired order
        results.forEach(function(result) {
            // do something with each result
        });
    }
});

अच्छा काम! हालांकि क्वेरी स्तर पर ऐसा करने में सक्षम होना अच्छा होगा। कुछ इस तरह var query = collection.find( { conditions } ).sort({$natural : -1}).reverse().limit(N)
inwpitrust 20

4

@ बिन चेन,

आप एक संग्रह में दस्तावेजों के सबसेट की नवीनतम एन प्रविष्टियों के लिए एक एकत्रीकरण का उपयोग कर सकते हैं। यहां समूह के बिना एक सरल उदाहरण दिया गया है (जो आप इस मामले में चरण 4 और 5 के बीच कर रहे हैं)।

यह नवीनतम 20 प्रविष्टियाँ देता है ("टाइमस्टैम्प" नामक क्षेत्र पर आधारित), आरोही क्रमबद्ध। इसके बाद परिणाम में प्रत्येक दस्तावेज़ _id, टाइमस्टैम्प और जो भी_फ़ील्ड_यौ_वांट_तो_शो प्रोजेक्ट करता है।

var pipeline = [
        {
            "$match": { //stage 1: filter out a subset
                "first_field": "needs to have this value",
                "second_field": "needs to be this"
            }
        },
        {
            "$sort": { //stage 2: sort the remainder last-first
                "timestamp": -1
            }
        },
        {
            "$limit": 20 //stage 3: keep only 20 of the descending order subset
        },
        {
            "$sort": {
                "rt": 1 //stage 4: sort back to ascending order
            }
        },
        {
            "$project": { //stage 5: add any fields you want to show in your results
                "_id": 1,
                "timestamp" : 1,
                "whatever_field_you_want_to_show": 1
            }
        }
    ]

yourcollection.aggregate(pipeline, function resultCallBack(err, result) {
  // account for (err)
  // do something with (result)
}

इसलिए, परिणाम कुछ इस तरह दिखाई देगा:

{ 
    "_id" : ObjectId("5ac5b878a1deg18asdafb060"),
    "timestamp" : "2018-04-05T05:47:37.045Z",
    "whatever_field_you_want_to_show" : -3.46000003814697
}
{ 
    "_id" : ObjectId("5ac5b878a1de1adsweafb05f"),
    "timestamp" : "2018-04-05T05:47:38.187Z",
    "whatever_field_you_want_to_show" : -4.13000011444092
}

उम्मीद है की यह मदद करेगा।


1
धन्यवाद @ lauri108! इस और संबंधित प्रश्नों के सभी उत्तरों में से, यह "काम करने के लिए विश्वसनीय और विश्वसनीय समाधान है कि कैसे लास्ट एन डॉक्स प्राप्त करें"। और एक क्वेरी में करने के लिए पर्याप्त सरल है। काम हो गया।
randomsock

@randomsock अगर आपको यह पसंद है, तो इसे वोट करें :)
lauri108

4

आपके संग्रह के आकार के आधार पर छंटनी, स्किपिंग और बहुत कुछ धीमा हो सकता है।

यदि आपके पास कुछ मानदंडों द्वारा अनुक्रमित संग्रह है, तो बेहतर प्रदर्शन प्राप्त किया जाएगा; और फिर आप मिनट () कर्सर का उपयोग कर सकते हैं:

सबसे पहले, आप के साथ अनुक्रमणिका का संग्रह db.collectionName.setIndex( yourIndex ) आप आरोही या अवरोही क्रम का उपयोग कर सकते हैं, जो शांत है, क्योंकि आप हमेशा "एन अंतिम आइटम" चाहते हैं ... इसलिए यदि आप अवरोही क्रम से सूचकांक करते हैं तो यह "पहले एन आइटम" प्राप्त करने के समान है। ।

तब आप अपने संग्रह का पहला आइटम ढूंढते हैं और खोज में न्यूनतम मानदंड के रूप में इसके सूचकांक क्षेत्र मान का उपयोग करते हैं:

db.collectionName.find().min(minCriteria).hint(yourIndex).limit(N)

यहाँ मिनट () कर्सर: https://docs.mongodb.com/manual/reference/method/curs.n/


केवल जवाब है कि प्रदर्शन को ध्यान में रखता है, महान इसके अलावा :)
zardilior

क्या यह उत्तर आदेश की गारंटी देता है?
जरदिल

हां, यह आपके सूचकांक के आधार पर गारंटी देता है
जोओ ओटेरो

जाहिरा तौर पर आप केवल मिनट भूल सकते हैं और उपयोग कर सकते हैं: db.collectionName.find().hint(yourIndex).limit(N) यदि सूचकांक अवरोही क्रम में है तो आपको एन न्यूनतम मान मिलते हैं।
पड़ाव


0
db.collection.find().hint( { $natural : -1 } ).sort(field: 1/-1).limit(n)

के अनुसार mongoDB प्रलेखन :

फ़ॉरवर्ड कलेक्शन स्कैन करने के लिए क्वेरी को बाध्य करने के लिए आप {$ प्राकृतिक: 1} निर्दिष्ट कर सकते हैं।

आप रिवर्स संग्रह स्कैन करने के लिए क्वेरी को बाध्य करने के लिए {$ प्राकृतिक: -1} भी निर्दिष्ट कर सकते हैं।


0

सरणी तत्वों को सीमित करने के लिए $ स्लाइस ऑपरेटर का उपयोग करें

GeoLocation.find({},{name: 1, geolocation:{$slice: -5}})
    .then((result) => {
      res.json(result);
    })
    .catch((err) => {
      res.status(500).json({ success: false, msg: `Something went wrong. ${err}` });
});

जहाँ जियोलोकेशन डेटा की सरणी है, वहाँ से हम पिछले 5 रिकॉर्ड प्राप्त करते हैं।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.