根据mongodb中的条件查询多个查找并将数据聚合到单个数组中

时间:2017-04-04 10:52:43

标签: mongodb collections mongodb-query aggregation-framework lookup

我在mongodb用户,帐户,船只,船员中有四个收藏;所有都有不同的数据结构。以下是样本:

用户集合

{
    "_id" : ObjectId("58b80a5f922a9656b78e86a7"),
    "email" : "bhargavksdn@gmail.com",
    "password" : "$2a$10$OVZfqHgKlB9gvIn38/DmL.h4/6n0g4frC8.QcHqHIbMQ0W4Fwv1BK",
    "access" : [ 
        {"id" : ObjectId("58b80a62922a9656b78e86a8"),"role" : "boats"}, 
        {"id" : ObjectId("580df78d3543ce1d905ffb11"),"role" : "accounts"}, 
        {"id" : ObjectId("563160bb671f0c130e6f09b5"),"role" : "accounts"}, 
        {"id" : ObjectId("58e35fea31d05f0e95e0c8fd"),"role" : "crews"}
    ],
    "admins" : [ "test1798@mailinator.com", "test179@mailinator.com", "xyz1793@mailinator.com", "xyz189@mailinator.com"]
}

船只收藏

{
    "_id" : ObjectId("58b80a62922a9656b78e86a8"),
    "name" : "brgvk",
    "email" : "bhargavksdn@gmail.com",
    "path" : "",
    "photo" : "",
    "accounts" : [ ObjectId("58b80a5f922a9656b78e86a7"), ObjectId("580df78d3543ce1d905ffb11")],
    "account_id" : "58b80a5f922a9656b78e86a7"
}

船员收集示例

{
    "_id" : ObjectId("58e35fea31d05f0e95e0c8fd"),
    "firstName" : "brgv",
    "lastName" : "k",
    "phone" : "",
    "email" : "bhargavksdn@gmail.com",
    "bio" : "",
    "photo" : "",
    "path" : "",
    "boats" : [],
    "accounts" : [ ObjectId("563160bb671f0c130e6f09b5"), ObjectId("58b80a5f922a9656b78e86a7")]
}
标识为580df78d3543ce1d905ffb11

帐户集合

{
    "_id" : ObjectId("580df78d3543ce1d905ffb11"),
    "profile" : {
        "accountName" : "Nightquest",
        "firstName" : "Jhon",
        "lastName" : "Smith",
        "phone" : "32122333333333",
         photo:"123.jpg",
         path:"1/23"
         "address" : "Melbourne"
    },
    "settings" : {
        color1:"red",
        color2:"blue"
    }
}
标识为563160bb671f0c130e6f09b5

帐户集合

{
    "_id" : ObjectId("563160bb671f0c130e6f09b5"),
    "profile" : {
        "accountName" : "Testing 123",
        "firstName" : "Tom",
        "lastName" : "Kru",
        photo:"123.jpg",
         path:"1/23"
        "phone" : "04181459",
        "address" : "Melbourne"
    },
     "settings" : {
        color1:"green",
        color2:"yellow"
    }
}

现在我正在使用以下聚合管道,我可以查询数据

db.users.aggregate(
    // Pipeline
    [
        {
            $unwind: { "path": "$access" }
        },
        {
            $project: { "roleId": "$access.id", "email": "$email" }
        },
        {
            $lookup: {
                    "from" :"accounts",
                    "localField": "roleId",
                    "foreignField": "_id",
                    "as": "accounts"
            }
        },
        {
            $lookup: {
                    "from" :"crews",
                    "localField": "roleId",
                    "foreignField": "_id",
                    "as": "crews"
            }
        },
        {
            $lookup: {
                    "from" :"boats",
                    "localField": "roleId",
                    "foreignField": "_id",
                    "as": "boats"
            }
        },
        {
            $unwind: { 
              "path": "$boats",
              "preserveNullAndEmptyArrays": true
             }
        },
        {
            $unwind: { 
              "path": "$crews",
              "preserveNullAndEmptyArrays": true
             }
        },
        {
            $unwind: { 
              "path": "$accounts",
              "preserveNullAndEmptyArrays": true
             }
        },
        {
            $group: { "_id": "$_id", 
               "email" : { 
                 "$first": "$email"
               }, 
               "accounts": { 
                    "$addToSet" : { 
                                 roleId:"$accounts._id",
                                 name:"$accounts.profile.accountName",
                                 "role":{$literal: 'accounts'} ,
                                 path:"$accounts.profile.path",
                                 photo:"$accounts.profile.photo"
                                 } 
               }, 
               "boats": {  

                               "$addToSet" : { 
                                 roleId:"$boats._id",
                                 name:"$boats.name",
                                 "role":{$literal: 'boats'} ,
                                 path:"$boats.path",
                                 photo:"$boats.photo"
                                 } 
               },
               "crews": {  
                  "$addToSet" : { 
                                 roleId:"$crews._id",
                                 name:{ "$concat": [ "$crews.firstName", "$crews.lastName" ] }
                                 "role":{$literal: 'crews'} ,
                                 path:"$crews.path",
                                 photo:"$crews.photo"
                                 } 
               } 
            },


        },
        {
            "$project":{
                "_id": 1,
                 "email": 1,
                 "access": { "$setUnion": [ "$accounts", "$boats", "$crews" ]  }
              }
        }


    ]
)    

虽然查询有效,但它会将空字段插入到访问属性的数组

[ 
    {
        "roleId" : ObjectId("58e35fea31d05f0e95e0c8fd"),
        "name" : "brgv k",
        "role" : "crews",
        "path" : "",
        "photo" : ""
    }, 
    {
        "role" : "boats"
    }, 
    {
        "name" : null,
        "role" : "crews"
    }, 
    {
        "role" : "accounts"
    }, 
    {
        "roleId" : ObjectId("580df78d3543ce1d905ffb11"),
        "name" : "Nightquest",
        "role" : "accounts"
    }, 
    {
        "roleId" : ObjectId("58b80a62922a9656b78e86a8"),
        "name" : "brgvk",
        "role" : "boats",
        "path" : "",
        "photo" : ""
    }, 
]

我想删除没有与roleId相关联的对象。

1 个答案:

答案 0 :(得分:1)

db.users.aggregate(

// Pipeline
[
    // Stage 1
    {
        $match: {
            "email": "bhargavksdn@gmail.com"
        }
    },

    // Stage 2
    {
        $unwind: { "path": "$access" }
    },

    // Stage 3
    {
        $project: { "roleId": "$access.id", "role": "$access.role", "email": "$email" }
    },

    // Stage 4
    {
        $lookup: {
                "from" :"accounts",
                "localField": "roleId",
                "foreignField": "_id",
                "as": "accounts"
        }
    },



    // Stage 5
    {
        $lookup: {
                "from" :"crews",
                "localField": "roleId",
                "foreignField": "_id",
                "as": "crews"
        }
    },

    // Stage 6
    {
        $lookup: {
                "from" :"boats",
                "localField": "roleId",
                "foreignField": "_id",
                "as": "boats"
        }
    },

    // Stage 7
    {
        $unwind: { 
          "path": "$boats",
          "preserveNullAndEmptyArrays": true
         }
    },
    {
        $unwind: { 
          "path": "$crews",
          "preserveNullAndEmptyArrays": true
         }
    },
    {
        $unwind: { 
          "path": "$accounts",
          "preserveNullAndEmptyArrays": true
         }
    },

    // Stage 11
    // Stage 11
    {
        $group: { "_id": "$_id", 
           "email" : { 
             "$first": "$email"
           }, 

           "accounts": { 


                "$addToSet" : { 
                             roleId:"$accounts._id",
                             name:"$accounts.profile.accountName",
                              "role":{"$cond": { "if": { "$eq": [ "$role", "accounts" ] }, 
                                        "then": "accounts","else": null}},
                             path:"$accounts.profile.path",
                             photo:"$accounts.profile.photo"
                             } 
           }, 
           "boats": {  


                           "$addToSet" : { 
                             roleId:"$boats._id",
                             name:"$boats.name",
                             "role":{"$cond": { "if": { "$eq": [ "$role", "boats" ] }, 
                                        "then": "boats","else": null}},
                             path:"$boats.path",
                             photo:"$boats.photo"
                             } 
           },
           "crews": {  

              "$addToSet" : { 
                             roleId:"$crews._id",
                             name:{ "$concat": [ "$crews.firstName"," ", "$crews.lastName" ] },
                             "role":{"$cond": { "if": { "$eq": [ "$role", "crews" ] }, 
                                        "then": "crews","else": null}},
                             path:"$crews.path",
                             photo:"$crews.photo"
                             } 
           } 
        },
    },        
            {
                "$project":{
                    "_id": 1,
                     "email": 1,
                     "access": { "$setUnion": ["$accounts", "$boats", "$crews" ]  }
                  }
            },

            { 
                "$project": {
                      "_id": 1,
                    "email": 1,
                    access: {
                        $filter: {
                           input: "$access",
                           as: "item",
                             cond: { $ne: [ "$$item.role", null ] }
                        }
                     }
          }
             }
]

);