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

मोंगो एकत्रीकरण में दस्तावेज़ में सरणी फ़ील्ड को कैसे मर्ज करें?

TLDR;

आधुनिक रिलीज़ को $reduce . का उपयोग करना चाहिए $setUnion . के साथ प्रारंभिक $group . के बाद जैसा दिखाया गया है:

db.collection.aggregate([
  { "$group": {
    "_id": { "Host": "$Host", "ArtId": "$ArtId" },
    "count": { "$sum": 1 },
    "tags": { "$addToSet": "$tags" }
  }},
  { "$addFields": {
    "tags": {
      "$reduce": {
        "input": "$tags",
        "initialValue": [],
        "in": { "$setUnion": [ "$$value", "$$this" ] }
      }
    }
  }}
])

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

हालांकि आपकी "गिनती" एक दिलचस्प समस्या है, लेकिन प्रारंभिक $group के बाद "डबल आराम" के उपयोग के माध्यम से आसानी से हल हो जाती है ऑपरेशन:

db.collection.aggregate([
    // Group on the compound key and get the occurrences first
    { "$group": {
        "_id": { "Host": "$Host", "ArtId": "$ArtId" },
        "tcount": { "$sum": 1 },
        "ttags": { "$push": "$tags" }
    }},

    // Unwind twice because "ttags" is now an array of arrays
    { "$unwind": "$ttags" },
    { "$unwind": "$ttags" },

    // Now use $addToSet to get the distinct values        
    { "$group": {
        "_id": "$_id",
        "tcount": { "$first": "$tcount" },
        "tags": { "$addToSet": "$ttags" }
    }},

    // Optionally $project to get the fields out of the _id key
    { "$project": {
        "_id": 0,
        "Host": "$_id.Host",
        "ArtId": "$_id.ArtId",
        "count": "$tcount",
        "tags": "$ttags"
    }}
])

$project . के साथ वह अंतिम बिट वहाँ भी है क्योंकि मैंने एकत्रीकरण पाइपलाइन के अन्य चरणों में प्रत्येक फ़ील्ड के लिए "अस्थायी" नामों का उपयोग किया है। ऐसा इसलिए है क्योंकि $project . में एक अनुकूलन है कि किसी भी "नए" फ़ील्ड को दस्तावेज़ में जोड़ने से पहले "पहले" दिखाई देने वाले मौजूदा चरण से फ़ील्ड को "कॉपी" करता है।

अन्यथा आउटपुट इस तरह दिखेगा:

{  "count":2 , "tags":[ "tag1", "tag2", "tag3" ], "Host": "abc.com", "ArtId": "123" }

जहां फ़ील्ड उसी क्रम में नहीं हैं जैसा आप सोच सकते हैं। वास्तव में तुच्छ, लेकिन यह कुछ लोगों के लिए मायने रखता है, इसलिए यह समझाने लायक है कि क्यों और कैसे संभालना है।

तो $unwind आइटम को अलग रखने का काम करता है और सरणियों में नहीं, और $group . कर रहा है पहले आपको "ग्रुपिंग" कुंजी की घटनाओं की "गिनती" प्राप्त करने की अनुमति देता है।

$first बाद में उपयोग किया जाने वाला ऑपरेटर उस "गिनती" मान को "रखता" है, क्योंकि इसे "टैग" सरणी में मौजूद प्रत्येक मान के लिए "डुप्लिकेट" मिला है। वैसे भी यह सब समान मूल्य है इसलिए इससे कोई फर्क नहीं पड़ता। बस एक उठाओ।




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Mongoose दस्तावेज़ों के भीतर मुक्त-फ़ॉर्म JSON डेटा की अनुमति कैसे दें?

  2. MongoDB डेटा स्टोर निर्देशिका बदलना

  3. ओपन सोर्स डेटाबेस को प्रबंधित करने का नया तरीका

  4. MongoDB के लिए PHP में आईएसओ दिनांक प्रारूप कैसे वापस करें?

  5. MongoDB के साथ पृष्ठ पर अंक लगाना