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

mongo $sum कंपाउंडेड $unwind करते समय और फिर कई क्षेत्रों पर $group

यह वास्तव में काफी आसान है, प्रत्येक सरणी के परिणामों को योग करने के लिए यह केवल समझदार की बात है कि कौन सा और "तत्वों का संयोजन" है। संक्षेप में, आपको शायद इसे अपने दस्तावेज़ों में वैसे भी करना चाहिए जैसा कि पहले पाइपलाइन चरण (चरणों) से स्पष्ट होना चाहिए।

तो MongoDB 2.6 और इससे अधिक के लिए कुछ सहायक तरीके हैं:

db.events.aggregate([
    { "$project": {
        "app_id": 1,
        "event_count": 1,
        "all_events": {
            "$setUnion": [
                { "$map": {
                    "input": "$events",
                    "as": "el",
                    "in": {
                        "type": "$$el.type",
                        "value": "$$el.value",
                        "class": { "$literal": "A" }
                    }
                }},
                { "$map": {
                    "input": "$unique_events",
                    "as": "el",
                    "in": {
                        "type": "$$el.type",
                        "value": "$$el.value",
                        "class": { "$literal": "B" }
                    }
                }}
            ]
        }
    }},
    { "$unwind": "$all_events" },
    { "$group": {
        "_id": {
            "app_id": "$app_id",
            "class": "$all_events.class",
            "type": "$all_events.type"
        },
        "event_count": { "$sum": "$event_count" },
        "value": { "$sum": "$all_events.value" }
    }},
    { "$group": {
        "_id": "$_id.app_id",
        "event_count": { "$sum": "$event_count" },
        "events": {
            "$push": {
                "$cond": [
                    { "$eq": [ "$_id.class", "A" ] },
                    { "type": "$_id.type", "value": "$value" },
                    false
                ]
            }
        },
        "unique_events": {
            "$push": {
                "$cond": [
                    { "$eq": [ "$_id.class", "B" ] },
                    { "type": "$_id.type", "value": "$value" },
                    false
                ]
            }
        }
    }},
    { "$project": {
        "event_count": 1,
        "events": { "$setDifference": [ "$events", [false] ] },
        "unique_events": {
            "$setDifference": [ "$unique_events", [false] ]
        }
    }}
])

अधिकतर $setUnion में और $setDifference ऑपरेटरों। दूसरा मामला है $map , जो जगह में सरणियों को संसाधित करता है। के उपयोग के बिना सरणियों पर संचालन करना पूरी बात है $unwind . लेकिन वे निश्चित रूप से पूर्व संस्करणों में किए जा सकते हैं, इसमें थोड़ा और काम लगता है:

db.events.aggregate([
    { "$unwind": "$events" },
    { "$group": {
        "_id": "$_id",
        "app_id": { "$first": "$app_id" },
        "event_count": { "$first": "$event_count" },
        "events": {
            "$push": {
                "type": "$events.type",
                "value": "$events.value",
                "class": { "$const": "A" }
            }
        },
        "unique_events": { "$first": "$unique_events" }            
    }},
    { "$unwind": "$unique_events" },
    { "$group": {
        "_id": "$_id",
        "app_id": { "$first": "$app_id" },
        "event_count": { "$first": "$event_count" },
        "events": { "$first": "$events" },
        "unique_events": {
            "$push": {
                "type": "$unique_events.type",
                "value": "$unique_events.value",
                "class": { "$const": "B" }
            }
        }
    }},
    { "$project": {
        "app_id": 1,
        "event_count": 1,
        "events": 1,
        "unique_events": 1,
        "type": { "$const": [ "A","B" ] }
    }},
    { "$unwind": "$type" },
    { "$unwind": "$events" },
    { "$unwind": "$unique_events" },
    { "$group": {
        "_id": "$_id",
        "app_id": { "$first": "$app_id" },
        "event_count": { "$first": "$event_count" },
        "all_events": {
            "$addToSet": {
                "$cond": [
                     { "$eq": [ "$events.class", "$type" ] },
                     {
                         "type": "$events.type",
                         "value": "$events.value",
                         "class": "$events.class"
                     },
                     {
                         "type": "$unique_events.type",
                         "value": "$unique_events.value",
                         "class": "$unique_events.class"
                     }
                ]
            }
        }
    }},
    { "$unwind": "$all_events" },
   { "$group": {
        "_id": {
            "app_id": "$app_id",
            "class": "$all_events.class",
            "type": "$all_events.type"
        },
        "event_count": { "$sum": "$event_count" },
        "value": { "$sum": "$all_events.value" }
    }},
    { "$group": {
        "_id": "$_id.app_id",
        "event_count": { "$sum": "$event_count" },
        "events": {
            "$push": {
                "$cond": [
                    { "$eq": [ "$_id.class", "A" ] },
                    { "type": "$_id.type", "value": "$value" },
                    false
                ]
            }
        },
        "unique_events": {
            "$push": {
                "$cond": [
                    { "$eq": [ "$_id.class", "B" ] },
                    { "type": "$_id.type", "value": "$value" },
                    false
                ]
            }
        }
    }},
    { "$unwind": "$events" },
    { "$match": { "events": { "$ne": false } } },
    { "$group": {
        "_id": "$_id",
        "event_count": { "$first": "$event_count" },
        "events": { "$push": "$events" },
        "unique_events": { "$first": "$unique_events" }
    }},
    { "$unwind": "$unique_events" },
    { "$match": { "unique_events": { "$ne": false } } },
    { "$group": {
       "_id": "$_id",
        "event_count": { "$first": "$event_count" },
        "events": { "$first": "$events" },
        "unique_events": { "$push": "$unique_events" }
    }}
])

यह आपको वह परिणाम देता है जो आप चाहते हैं कि प्रत्येक सरणी एक साथ "सारांशित" हो और साथ ही मास्टर "event_count" सही परिणाम के साथ हो।

आपको शायद उन दोनों सरणियों को एक समान पहचानकर्ता के साथ संयोजन करने पर विचार करना चाहिए जो कि प्रदर्शित किए गए पाइपलाइनों में उपयोग किया गया है। यह हिस्सा काम का आधा है। दूसरा आधा इस बात पर विचार कर रहा है कि आपको सर्वोत्तम एप्लिकेशन प्रदर्शन के लिए कहीं संग्रह में पूर्व-एकत्रित परिणामों को संग्रहीत करना चाहिए।



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. ग्रोवी मिलान करने वाला कन्स्ट्रक्टर नहीं ढूंढ सका?

  2. मैं $match एकत्रीकरण में मानों की एक सरणी कैसे ढूंढ सकता हूं और परिणाम को समूहित कर सकता हूं?

  3. MongoDB में संग्रह को हटाने के 2 तरीके

  4. अवैध ब्रेक स्टेटमेंट (Node.js)

  5. एक नेवला स्कीमा पर एक सरणी गुण सहेजा जा रहा है