MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

अधिकतम उप दस्तावेज़ के साथ वापसी दस्तावेज़

सबसे पहले, आइए आपके डेटा को इस तरह दिखाते हैं कि लोग इसका उपयोग कर सकें और वांछित परिणाम दे सकें:

{ value: 1,
  _id: ObjectId('5cb9ea0c75c61525e0176f96'),
  name: 'Test',
  category: 'Development',
  subcategory: 'Programming Languages',
  status: 'Supported',
  description: 'Test',
  change:
   [ { version: 1,
       who: 'ATL User',
       when: new Date('2019-04-19T15:30:39.912Z'),
       what: 'Item Creation' },
     { version: 2,
       who: 'ATL Other User',
       when: new Date('2019-04-19T15:31:39.912Z'),
       what: 'Name Change' } ],
}

ध्यान दें कि "कब" तिथियां वास्तव में भिन्न हैं इसलिए एक $max<होगा /कोड> मूल्य और वे सिर्फ वही नहीं हैं। अब हम मामलों के माध्यम से भाग सकते हैं

केस 1 - "सिंगुलर" प्राप्त करें $max मान

यहां मूल मामला $arrayElemAt और $indexOfArray ऑपरेटरों को मैचिंग $max लौटाना होगा मूल्य:

db.items.aggregate([
  { "$match": {
    "subcategory": "Programming Languages", "name": { "$exists": true }
  }}, 
  { "$addFields": {
    "change": {
      "$arrayElemAt": [
        "$change",
        { "$indexOfArray": [
          "$change.when",
          { "$max": "$change.when" }
        ]}
      ]
    }
  }}
])

रिटर्न:

{
        "_id" : ObjectId("5cb9ea0c75c61525e0176f96"),
        "value" : 1,
        "name" : "Test",
        "category" : "Development",
        "subcategory" : "Programming Languages",
        "status" : "Supported",
        "description" : "Test",
        "change" : {
                "version" : 2,
                "who" : "ATL Other User",
                "when" : ISODate("2019-04-19T15:31:39.912Z"),
                "what" : "Name Change"
        }
}

मूल रूप से "$max":"$change.when" वह मान लौटाता है जो मानों की उस सरणी के भीतर से "अधिकतम" है। फिर आप $indexOfArray जो पहले . लौटाता है मिलान सूचकांक मिला। वह "सूचकांक" स्थिति (वास्तव में "कब" . की एक सरणी से उसी क्रम में ट्रांसपोज़ किए गए मान) का उपयोग तब $arrayElemAt के साथ किया जाता है "परिवर्तन" . से "संपूर्ण वस्तु" निकालने के लिए निर्दिष्ट अनुक्रमणिका स्थिति पर सरणी।

केस 2 - "एकाधिक" लौटाएं $max प्रविष्टियां

लगभग एक ही चीज़ $max के साथ है , इस समय को छोड़कर हम $filter एकाधिक "संभव" . को वापस करने के लिए $max से मेल खाने वाले मान मूल्य:

db.items.aggregate([
  { "$match": {
    "subcategory": "Programming Languages", "name": { "$exists": true }
  }}, 
  { "$addFields": {
    "change": {
      "$filter": {
        "input": "$change",
        "cond": {
          "$eq": [ "$$this.when", { "$max": "$change.when" } ]
        }
      }       
    }
  }}
])

रिटर्न:

{
        "_id" : ObjectId("5cb9ea0c75c61525e0176f96"),
        "value" : 1,
        "name" : "Test",
        "category" : "Development",
        "subcategory" : "Programming Languages",
        "status" : "Supported",
        "description" : "Test",
        "change" : [
                {
                        "version" : 2,
                        "who" : "ATL Other User",
                        "when" : ISODate("2019-04-19T15:31:39.912Z"),
                        "what" : "Name Change"
                }
        ]
}

तो $max निश्चित रूप से वही है लेकिन इस बार उस ऑपरेटर द्वारा लौटाए गए एकवचन मूल्य का उपयोग $eq $filter में तुलना . यह प्रत्येक सरणी तत्व का निरीक्षण करता है और वर्तमान . को देखता है "कब" मान ( "$$this.when" ) जहां "बराबर" तब तत्व वापस आ जाता है।

मूल रूप से पहले दृष्टिकोण के समान लेकिन अपवाद के साथ कि $filter अनुमति देता है "एकाधिक" तत्वों को लौटाना है। इसलिए सब कुछ उसी . के साथ $max मूल्य।

केस 3 - सरणी सामग्री को पूर्व-क्रमबद्ध करें।

अब आप ध्यान दें कि उदाहरण डेटा में मैंने शामिल किया था (आपके स्वयं से अनुकूलित लेकिन वास्तविक "अधिकतम" तिथि के साथ) "अधिकतम" मान वास्तव में अंतिम है सरणी में मान। यह स्वाभाविक रूप से एक परिणाम के रूप में हो सकता है $push कोड> (डिफ़ॉल्ट रूप से) "संलग्न" मौजूदा सरणी सामग्री के अंत तक। तो "नया" प्रविष्टियाँ अंत . पर होंगी सरणी का।

यह निश्चित रूप से डिफ़ॉल्ट है व्यवहार, लेकिन इसके अच्छे कारण हैं कि आप "हो सकता है" इसे बदलना चाहते हैं। संक्षेप में सर्वश्रेष्ठ "सबसे हाल का" . प्राप्त करने का तरीका सरणी प्रविष्टि वास्तव में पहला तत्व लौटाना है सरणी से।

आपको वास्तव में केवल यह सुनिश्चित करने की आवश्यकता है कि "सबसे हाल का" वास्तव में जोड़ा जाता है पहले आखिरी के बजाय . दो दृष्टिकोण हैं:

  1. $position का इस्तेमाल करें सरणी आइटम को "प्री-पेंड" करने के लिए: यह $push का सरल संशोधक है 0 . का उपयोग करके स्थिति हमेशा सामने . में जोड़ने के लिए :

    db.items.updateOne(
      { "_id" : ObjectId("5cb9ea0c75c61525e0176f96") },
      { "$push": {
          "change": {
            "$each": [{
              "version": 3,
              "who": "ATL User",
              "when": new Date(),
              "what": "Another change"
            }],
            "$position": 0
          }
       }}
    )
    

    यह दस्तावेज़ को इसमें बदल देगा:

    {
        "_id" : ObjectId("5cb9ea0c75c61525e0176f96"),
        "value" : 1,
        "name" : "Test",
        "category" : "Development",
        "subcategory" : "Programming Languages",
        "status" : "Supported",
        "description" : "Test",
        "change" : [
                {
                        "version" : 3,
                        "who" : "ATL User",
                        "when" : ISODate("2019-04-20T02:40:30.024Z"),
                        "what" : "Another change"
                },
                {
                        "version" : 1,
                        "who" : "ATL User",
                        "when" : ISODate("2019-04-19T15:30:39.912Z"),
                        "what" : "Item Creation"
                },
                {
                        "version" : 2,
                        "who" : "ATL Other User",
                        "when" : ISODate("2019-04-19T15:31:39.912Z"),
                        "what" : "Name Change"
                }
        ]
    }
    

ध्यान दें कि इसके लिए आपको वास्तव में जाने और अपने सभी सरणी तत्वों को पहले से "रिवर्स" करने की आवश्यकता होगी ताकि "नवीनतम" पहले से ही सामने हो ताकि ऑर्डर बनाए रखा जा सके। शुक्र है कि यह कुछ हद तक दूसरे दृष्टिकोण में शामिल है...

  1. $sort का इस्तेमाल करें प्रत्येक $push : और यह अन्य संशोधक है जो वास्तव में प्रत्येक नए आइटम जोड़ पर परमाणु रूप से "पुनः क्रमबद्ध" करता है। सामान्य उपयोग मूल रूप से $each के किसी भी नए आइटम के साथ समान है ऊपर के रूप में, या यहां तक ​​कि केवल एक "रिक्त" सरणी लागू करने के लिए $क्रमबद्ध केवल मौजूदा डेटा के लिए:

    db.items.updateOne(
      { "_id" : ObjectId("5cb9ea0c75c61525e0176f96") },
      { "$push": {
          "change": {
            "$each": [],
            "$sort": { "when": -1 } 
          }
       }}
    )
    

    इसमें परिणाम:

    {
            "_id" : ObjectId("5cb9ea0c75c61525e0176f96"),
            "value" : 1,
            "name" : "Test",
            "category" : "Development",
            "subcategory" : "Programming Languages",
            "status" : "Supported",
            "description" : "Test",
            "change" : [
                    {
                            "version" : 3,
                            "who" : "ATL User",
                            "when" : ISODate("2019-04-20T02:40:30.024Z"),
                            "what" : "Another change"
                    },
                    {
                            "version" : 2,
                            "who" : "ATL Other User",
                            "when" : ISODate("2019-04-19T15:31:39.912Z"),
                            "what" : "Name Change"
                    },
                    {
                            "version" : 1,
                            "who" : "ATL User",
                            "when" : ISODate("2019-04-19T15:30:39.912Z"),
                            "what" : "Item Creation"
                    }
            ]
    }
    

    यह समझने में एक मिनट लग सकता है कि आप $push<क्यों करेंगे /कोड> $sort करने के लिए इस तरह की एक सरणी, लेकिन सामान्य इरादा तब होता है जब एक सरणी में संशोधन किया जा सकता है जो एक संपत्ति को "बदल" देता है जैसे दिनांक मूल्य को क्रमबद्ध किया जा रहा है और आप उन परिवर्तनों को दर्शाने के लिए इस तरह के एक बयान का उपयोग करेंगे। या वास्तव में केवल $sort और इसे काम करने दें।

तो क्यों "स्टोर" सरणी इस तरह आदेश दिया? जैसा कि पहले उल्लेख किया गया है कि आप पहला . चाहते हैं आइटम के रूप में "सबसे हाल का" , और फिर वापस लौटने की क्वेरी बस बन जाती है:

db.items.find(
  {
    "subcategory": "Programming Languages",
    "name": { "$exists": true }
  },
  { "change": { "$slice": 1 } }
)

रिटर्न:

{
        "_id" : ObjectId("5cb9ea0c75c61525e0176f96"),
        "value" : 1,
        "name" : "Test",
        "category" : "Development",
        "subcategory" : "Programming Languages",
        "status" : "Supported",
        "description" : "Test",
        "change" : [
                {
                        "version" : 3,
                        "who" : "ATL User",
                        "when" : ISODate("2019-04-20T02:40:30.024Z"),
                        "what" : "Another change"
                }
        ]
}

तो $slice तब ज्ञात अनुक्रमित द्वारा सरणी आइटम निकालने के लिए उपयोग किया जा सकता है। तकनीकी रूप से आप केवल -1 . का उपयोग कर सकते हैं वहाँ अंतिम . वापस करने के लिए किसी भी तरह से सरणी का आइटम, लेकिन जहां सबसे हाल ही में सबसे पहले पुनर्क्रमण अन्य चीजों के लिए अनुमति देता है जैसे कि अंतिम संशोधन की पुष्टि एक निश्चित उपयोगकर्ता द्वारा की गई थी, और/या अन्य शर्तें जैसे दिनांक सीमा बाधा। यानी:

db.items.find(
  {
    "subcategory": "Programming Languages",
    "name": { "$exists": true },
    "change.0.who": "ATL User",
    "change.0.when": { "$gt": new Date("2018-04-01") }
  },
  { "change": { "$slice": 1 } }
)

यहां ध्यान दें कि "change.-1.when" . जैसा कुछ है एक अवैध बयान है, यही कारण है कि हम सरणी को फिर से व्यवस्थित करते हैं ताकि आप कानूनी . का उपयोग कर सकें 0 पहले . के लिए -1 . के बजाय अंतिम . के लिए ।

निष्कर्ष

तो आप कई अलग-अलग चीजें कर सकते हैं, या तो सरणी सामग्री को फ़िल्टर करने के लिए एकत्रीकरण दृष्टिकोण का उपयोग करके या मानक क्वेरी रूपों के माध्यम से डेटा को वास्तव में संग्रहीत करने के तरीके में कुछ संशोधन करने के बाद। किसका उपयोग करना है यह आपकी अपनी परिस्थितियों पर निर्भर करता है, लेकिन यह ध्यान दिया जाना चाहिए कि मानक क्वेरी फ़ॉर्म में से कोई भी एकत्रीकरण ढांचे या किसी भी गणना किए गए ऑपरेटरों के माध्यम से किसी भी हेरफेर की तुलना में विशेष रूप से तेज चलेगा।




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. उल्का, मोंगोडब, स्पेसबार, मैं केवल 2 दशमलव स्थानों को कैसे प्रदर्शित करूं

  2. मोंगोडब (कोड =बाहर निकल गया, स्थिति =14) विफल रहा लेकिन कोई स्पष्ट त्रुटि नहीं है

  3. mongodb में आंतरिक रूप से मेल खाने वाले फ़ील्ड

  4. नेवला पृष्ठ पर अंक लगाना और फ़िल्टर

  5. Mongoid store_in यादृच्छिक परिणाम उत्पन्न करता है

© कॉपीराइट http://hi.sqldat.com सर्वाधिकार सुरक्षित