MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Kueri hierarkis dengan Mongo menggunakan $graphLookup

Saya percaya bahwa memiliki level bidang kita dapat membangun struktur hierarkis dari array menggunakan $reduce. Untuk mencapai itu kita perlu mendapatkan reportees diurutkan berdasarkan penurunan level setelah $graphLookup . Sayangnya satu-satunya cara untuk melakukannya saat ini adalah dengan menggunakan $unwind + $sort + $group yang membuat agregasi menjadi cukup panjang.

Kemudian kita dapat memproses array yang dipesan itu menggunakan $reduce . Di setiap langkah kita hanya perlu menambahkan seorang karyawan ke kumpulan hasil termasuk reportees dari tingkat sebelumnya. Selain itu, kita perlu mendeteksi kapan level perubahan selama pemrosesan kami dan mengatur ulang susunan pembantu dalam kasus tersebut.

$addFields hanya menggantikan reportees yang ada lapangan dalam hal ini. $concatArrays memungkinkan kita untuk menambahkan karyawan saat ini ($$this ) ke hasil. Menggunakan $filter kita bisa mendapatkan reportees dari tingkat yang lebih rendah.

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()

Solusi di atas harus bekerja untuk beberapa level. Keluaran:

{
    "_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. Dampak Performa Meltdown pada MongoDB:AWS, Azure &DigitalOcean

  2. MongoDB:mongoimport kehilangan koneksi saat mengimpor file besar

  3. Node + Mongoose:Dapatkan ID yang terakhir dimasukkan?

  4. Bagaimana menemukan nama bidang MongoDB pada kedalaman yang sewenang-wenang

  5. Pertempuran Database NoSQL - Membandingkan Fungsi NoSQL MongoDB &MSSQL