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

मैच की स्थिति और सरणी से नवीनतम तिथि

यहां मूल अवधारणा यह है कि शर्तों के लिए सरणी तत्वों को "फ़िल्टर" करने के लिए शर्तों को लागू करने के लिए आपको एकत्रीकरण ढांचे की आवश्यकता है। उपलब्ध संस्करण के आधार पर विभिन्न तकनीकें हैं जिन्हें लागू किया जा सकता है।

सभी मामलों में यह परिणाम है:

{
    "_id" : ObjectId("593921425ccc8150f35e7664"),
    "user1" : 1,
    "user2" : 4,
    "messages" : {
            "sender" : 1,
            "datetime" : ISODate("2017-06-09T10:04:50Z"),
            "body" : "hiii 1"
    }
}
{
    "_id" : ObjectId("593921425ccc8150f35e7663"),
    "user1" : 1,
    "user2" : 3,
    "messages" : {
            "sender" : 1,
            "datetime" : ISODate("2017-06-10T10:04:50Z"),
            "body" : "hiii 2"
    }
}
{
    "_id" : ObjectId("593921425ccc8150f35e7662"),
    "user1" : 1,
    "user2" : 2,
    "messages" : {
            "sender" : 1,
            "datetime" : ISODate("2017-06-08T10:04:50Z"),
            "body" : "hiii 0"
    }
}

MongoDB 3.4 और इसके बाद के संस्करण

db.chat.aggregate([
  { "$match": { "messages.sender": 1 } },
  { "$replaceRoot": {
    "newRoot": {
      "$let": {
        "vars": {
          "messages": {
            "$filter": {
              "input": "$messages",
              "as": "m",
              "cond": { "$eq": [ "$$m.sender", 1 ] }
            }
          },
          "maxDate": {
            "$max": {
              "$map": {
                "input": {
                  "$filter": {
                    "input": "$messages",
                    "as": "m",
                    "cond": { "$eq": [ "$$m.sender", 1 ] }
                  }
                },
                "as": "m",
                "in": "$$m.datetime"
              }
            }
          }
        },
        "in": {
          "_id": "$_id",
          "user1": "$user1",
          "user2": "$user2",
          "messages": {
            "$arrayElemAt": [
              { "$filter": {
                "input": "$$messages",
                "as": "m",
                "cond": { "$eq": [ "$$m.datetime", "$$maxDate" ] }
              }},
              0
            ]
          }    
        }
      }
    }
  }}
])

यह सबसे कारगर तरीका है जो $replaceRoot<का लाभ उठाता है /कोड> जो हमें <का उपयोग करके "प्रतिस्थापित" संरचना में उपयोग करने के लिए चर घोषित करने की अनुमति देता है। कोड>$लेट . यहां मुख्य लाभ यह है कि इसके लिए केवल "दो" पाइपलाइन चरणों की आवश्यकता होती है।

आपके द्वारा उपयोग की जाने वाली सरणी सामग्री से मिलान करने के लिए $filter कोड> जहां आप $eq लागू करते हैं "प्रेषक" . के मान का परीक्षण करने के लिए तार्किक संचालन . जहां कंडीशन मेल खाती है, वहां केवल मैचिंग ऐरे एंट्रीज ही वापस आती हैं।

उसी का उपयोग करना $filter ताकि केवल मेल खाने वाली "प्रेषक" प्रविष्टियों पर विचार किया जा सके, फिर हम $अधिकतम "datetime" . में मानों के लिए "फ़िल्टर की गई" सूची पर . $अधिकतम ]5 मान शर्तों के अनुसार "नवीनतम" तिथि है।

हम यह मान चाहते हैं ताकि हम बाद में "फ़िल्टर किए गए" सरणी से लौटाए गए परिणामों की तुलना इस "maxDate" से कर सकें। "in" . के अंदर क्या होता है $let का ब्लॉक जहां फ़िल्टर की गई सामग्री के लिए पहले घोषित किए गए दो "चर" और "maxDate" को फिर से $filter वापस करने के लिए केवल वही मान होना चाहिए जो "नवीनतम तिथि" वाली दोनों शर्तों को पूरा करता हो।

चूँकि आप केवल "एक" परिणाम चाहते हैं, हम $arrayElemAt का उपयोग करते हैं सरणी के बजाय मान का उपयोग करने के लिए।

मोंगोडीबी 3.2

db.chat.aggregate([
  { "$match": { "messages.sender": 1 } },
  { "$project": {
    "user1": 1,
    "user2": 1,
    "messages": {
      "$filter": {
        "input": "$messages",
        "as": "m",
        "cond": { "$eq": [ "$$m.sender", 1 ] }
      }
    },
    "maxDate": {
      "$max": {
        "$map": {
          "input": {
            "$filter": {
              "input": "$messages",
              "as": "m",
              "cond": { "$eq": [ "$$m.sender", 1 ] }
            }
          },
          "as": "m",
          "in": "$$m.datetime"
        }
      }
    }         
  }},
  { "$project": {
    "user1": 1,
    "user2": 1,
    "messages": {
      "$arrayElemAt":[
       { "$filter": {
         "input": "$messages",
          "as": "m",
          "cond": { "$eq": [ "$$m.datetime", "$maxDate" ] }
       }},
       0
      ]
    }
  }}
])

यह मूल रूप से वर्णित प्रक्रिया के समान है, लेकिन $ के बिना रिप्लेसरूट पाइपलाइन चरण, हमें दो में आवेदन करने की आवश्यकता है $project कोड> चरण। इसका कारण यह है कि हमें अंतिम $फ़िल्टर , और यह कंपाउंड स्टेटमेंट में करने के लिए उपलब्ध नहीं है, इसलिए इसके बजाय हम पाइपलाइनों को विभाजित करते हैं। इसका संचालन की कुल लागत पर बहुत कम प्रभाव पड़ता है।

MongoDB 2.6 से 3.0 में हम <को छोड़कर यहां अधिकांश तकनीक का उपयोग कर सकते हैं। कोड>$arrayElemAt और या तो एकल प्रविष्टि के साथ "सरणी" परिणाम स्वीकार करें या में डालें $अनविंड अब एकल प्रविष्टि क्या होनी चाहिए, इससे निपटने के लिए चरण।

MongoDB पुराने संस्करण

db.chat.aggregate([
  { "$match": { "messages.sender": 1 } },
  { "$unwind": "$messages" },
  { "$match": { "messages.sender": 1 } },
  { "$sort": { "_id": 1, "messages.datetime": -1 } },
  { "$group": {
    "_id": "$_id",
    "user1": { "$first": "$user1" },
    "user2": { "$first": "$user2" },
    "messages": { "$first": "$messages" }
  }}
])

हालांकि यह संक्षिप्त दिखता है, यह अब तक का सबसे महंगा ऑपरेशन है। यहां आपको $unwind का इस्तेमाल करना चाहिए सरणी तत्वों के लिए शर्तों को लागू करने के लिए। यह एक बहुत ही महंगी प्रक्रिया है क्योंकि यह प्रत्येक सरणी प्रविष्टि के लिए प्रत्येक दस्तावेज़ की एक प्रति तैयार करता है, और अनिवार्य रूप से आधुनिक ऑपरेटरों द्वारा प्रतिस्थापित किया जाता है जो "फ़िल्टरिंग" के मामले में इससे बचते हैं।

दूसरा $match यहां चरण किसी भी तत्व (अब "दस्तावेज़") को त्याग देता है जो "प्रेषक" स्थिति से मेल नहीं खाता। फिर हम एक $sort लागू करते हैं _id . द्वारा प्रत्येक दस्तावेज़ के लिए "नवीनतम" तिथि को शीर्ष पर रखने के लिए , इसलिए दो "सॉर्ट" कुंजियाँ।

अंत में हम $group लागू करते हैं केवल मूल दस्तावेज़ को संदर्भित करने के लिए, $first का उपयोग करके "शीर्ष पर" तत्व प्राप्त करने के लिए संचायक के रूप में।




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. अनुचित रूप से धीमी MongoDB क्वेरी, भले ही क्वेरी सरल हो और अनुक्रमणिका के साथ संरेखित हो

  2. MongoTemplate के साथ क्रमबद्ध विशिष्ट मान प्राप्त करें

  3. अजगर / bcrypt का उपयोग कर उपयोगकर्ताओं के संग्रह में mongodb में नमकीन हैश के रूप में पासवर्ड सहेजें

  4. खाली सरणी दस्तावेज़ को क्वेरी में प्रकट होने से रोकती है

  5. सी # में स्व-हस्ताक्षरित प्रमाणपत्रों के साथ मोंगोडीबी एसएसएल