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

$graphLookup . का उपयोग करके मोंगो के साथ पदानुक्रमित प्रश्न

मेरा मानना ​​है कि स्तर फ़ील्ड हम $reduce का उपयोग करके एक सरणी से पदानुक्रमित संरचना बना सकते हैं। इसे प्राप्त करने के लिए हमें reportees . प्राप्त करने की आवश्यकता है $graphLookup . के बाद अवरोही स्तर के अनुसार क्रमित . दुर्भाग्य से वर्तमान में ऐसा करने का एकमात्र तरीका $unwind + $sort + $group का उपयोग करना है जो एकत्रीकरण को काफी लंबा बनाता है।

फिर हम $reduce . का उपयोग करके उस ऑर्डर किए गए ऐरे को प्रोसेस कर सकते हैं . प्रत्येक चरण में हमें केवल एक कर्मचारी को उसके reportees . सहित परिणाम सेट में जोड़ना होगा पिछले स्तर से। इसके अतिरिक्त हमें यह पता लगाने की आवश्यकता है कि level . कब हमारे प्रसंस्करण के दौरान परिवर्तन और उस स्थिति में सहायक सरणियों को पुनर्व्यवस्थित करें।

$addFields बस मौजूदा reportees . को बदल देता है इस मामले में क्षेत्र। $concatArrays हमें वर्तमान कर्मचारी को जोड़ने की अनुमति देता है ($$this ) परिणाम के लिए। $filter का उपयोग करके हम reportees प्राप्त कर सकते हैं निचले स्तर से।

db.getCollection('employees').aggregate([
    {
        $match: {
            empId : "10"
        }
    },
    {
        $graphLookup: {
            from: "employees",
            startWith: "$empId",
            connectFromField: "empId",
            connectToField: "managerId",
            as: "reportees",
            maxDepth: 4,
            depthField: "level"
        }
    },
    {
        $project: {
            "empId":1,
            "managerId":1,
            "reportees.empId":1,
            "reportees.name":1,
            "reportees.managerId":1,
            "reportees.level":1
        }
    },
    {
        $unwind: "$reportees"
    },
    {
        $sort: { "reportees.level": -1 }
    },
    {
        $group: {
            _id: "$_id",
            empId: { $first: "$empId" },
            managerId: { $first: "$managerId" },
            reportees: { $push: "$reportees" }
        }
    },
    {
        $addFields: {
            reportees: {
                $reduce: {
                    input: "$reportees",
                    initialValue: {
                        currentLevel: -1,
                        currentLevelEmployees: [],
                        previousLevelEmployees: []
                    },
                    in: {
                        $let: {
                            vars: {
                                prev: { 
                                    $cond: [ 
                                        { $eq: [ "$$value.currentLevel", "$$this.level" ] }, 
                                        "$$value.previousLevelEmployees", 
                                        "$$value.currentLevelEmployees" 
                                    ] 
                                },
                                current: { 
                                    $cond: [ 
                                        { $eq: [ "$$value.currentLevel", "$$this.level" ] }, 
                                        "$$value.currentLevelEmployees", 
                                        [] 
                                    ] 
                                }
                            },
                            in: {
                                currentLevel: "$$this.level",
                                previousLevelEmployees: "$$prev",
                                currentLevelEmployees: {
                                    $concatArrays: [
                                        "$$current", 
                                        [
                                            { $mergeObjects: [ 
                                                "$$this", 
                                                { reportees: { $filter: { input: "$$prev", as: "e", cond: { $eq: [ "$$e.managerId", "$$this.empId"  ] } } } } 
                                            ] }
                                        ]
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    {
        $addFields: { reportees: "$reportees.currentLevelEmployees" }
    }
]).pretty()

उपरोक्त समाधान कई स्तरों के लिए काम करना चाहिए। आउटपुट:

{
    "_id" : "10",
    "empId" : "10",
    "managerId" : "15",
    "reportees" : [
        {
            "empId" : "6",
            "name" : "Employee6",
            "managerId" : "10",
            "level" : NumberLong(0),
            "reportees" : [
                {
                        "empId" : "1",
                        "name" : "Employee1",
                        "managerId" : "6",
                        "level" : NumberLong(1),
                        "reportees" : [ ]
                },
                {
                        "empId" : "2",
                        "name" : "Employee2",
                        "managerId" : "6",
                        "level" : NumberLong(1),
                        "reportees" : [ ]
                }
            ]
        },
        {
            "empId" : "8",
            "name" : "Employee8",
            "managerId" : "10",
            "level" : NumberLong(0),
            "reportees" : [
                {
                    "empId" : "5",
                    "name" : "Employee5",
                    "managerId" : "8",
                    "level" : NumberLong(1),
                    "reportees" : [ ]
                },
                {
                    "empId" : "4",
                    "name" : "Employee4",
                    "managerId" : "8",
                    "level" : NumberLong(1),
                    "reportees" : [ ]
                }
            ]
        }
    ]
}


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. एक फ़ील्ड नाम क्लासनाम मॉर्फिया द्वारा मोंगोडब में डाला जा रहा है

  2. _id फ़ील्ड के बिना mongoexport

  3. मैं कंसोल में MongoDB लॉग संदेशों को कैसे अक्षम कर सकता हूं?

  4. मोंगोडब समुच्चय (गिनती) एक साथ कई क्षेत्रों पर

  5. बढ़ती डेटा संरचना के साथ MongoDB प्रदर्शन