在数组中与其他内容相邻的地方使用Mongodb引用

时间:2019-04-11 12:22:01

标签: arrays mongodb aggregation-framework

我想在必须“归类到”一个查询的3个集合上使用mongodb聚合框架。问题是,当我使用$lookup引用另一个集合时,它将删除该引用所在的数组的其他内容。 以下是我的聚合开始于(用户)的集合:

{
    "_id" : ObjectId("5c9bea89f4fe8c37175ade58"),
    "kundennummer" : "000001",
    "passwort" : "xxx",
    "status" : "1",
    "onlinestatus" : true,
    "kontakt" : {
        "email" : "test@test.net"
    },
    "thing" : [ 
        {
            "thing_id" : 2,
            "onlinestatus" : false,
            "status" : true,
            "site" : [ 
                {
                    "site_id" : 3,
                    "status": true
                }, 
                {
                    "site_id" : 4,
                    "status": true
                }
            ],
            "refs" : [ 
                {
                    "thing_id" : 11,
                    "status" : true
                }, 
                {
                    "thing_id" : 22,
                    "status" : true
                }
            ]
        }
    ]
}

当我知道希望sitesite集合中给出的内容扩展时,如下所示:

{
    "_id": 11,
    "name": "test"
},
{
    "_id": 22,
    "name": "test2"
}

我尝试使用$lookup,而status: true消失了。

db.users.aggregate([{
    $lookup:
    {
        from: "sites",
        localField: "things.site.site_id",
        foreignField: "_id",
        as: "things.site"
    }
}])

编辑: 我要实现的目标如下:

{
    "_id" : ObjectId("5c9bea89f4fe8c37175ade58"),
    "kundennummer" : "000001",
    "passwort" : "xxx",
    "status" : "1",
    "onlinestatus" : true,
    "kontakt" : {
        "email" : "test@test.net"
    },
    "thing" : [ 
        {
            "thing_id" : 2,
            "onlinestatus" : false,
            "status" : true,
            "site" : [ 
                {
                    "site_id" : 11,
                    "status": true,
                    "name": "test"

                }, 
                {
                    "site_id" : 12,
                    "status": true,
                    "name": "test2"
                }
            ],
            "refs" : [ 
                {
                    "thing_id" : 11,
                    "status" : true,
                    "name": "test"
                }, 
                {
                    "thing_id" : 12,
                    "status" : true,
                    "name": "test2"
                }
            ]
        }
    ]
}

1 个答案:

答案 0 :(得分:0)

要在MongoDB聚合中的嵌入式文档上使用$ lookup,您需要使用$ unwind。它将为每个元素输出一个文档,然后您可以使用$ lookup。您还将通过以下查询从sites获得结果:

db.user.aggregate([
{
    $unwind:  "$thing"
},
{
    $unwind:   "$thing.site"      
},
{
    $unwind:   "$thing.refs"      
},
{
    $lookup: {
        from: 'sites',
        let: { 'siteId': '$thing.site.site_id' },
        pipeline: [
             {
                $match: { 
                    $expr: { 
                        $eq: ['$_id', '$$siteId'] 
                    }
                }
            },    
        ],
        as: 'siteObject'
    }
},
{
    $lookup: {
        from: 'things',
        let: { 'thingId': '$thing.refs.thing_id' },
        pipeline: [
             {
                $match: { 
                    $expr: { 
                        $eq: ['$_id', '$$thingId'] 
                    }
                }
            },    
        ],
        as: 'thingObject'
    }
},
{
    $unwind: "$siteObject"
},
{
    $unwind: "$thingObject"
},
{
    $project: {
        "_id" : 1,
        "kundennummer" : 1,
        "passwort" : 1,
        "status" : 1,
        "onlinestatus" : 1,
        "kontakt" : 1,
        "thing": [{
            "thing_id" : "$thing.thing_id",
            "onlinestatus" : "$thing.onlinestatus",
            "status" : "$thing.status",
            "site" : {
                "site_id":"$thing.site.site_id",
                "status":"$thing.site.status",
                "siteName":"$siteObject.siteName",
            }, 
            "refs" : {
                "thing_id":"$thing.refs.thing_id",
                "status":"$thing.refs.status",
                "siteName":"$thingObject.thingName",
            }, 
        }]
    }
},
{
    $unwind: "$thing"
},
{
    $group: {
        _id: { 
            "_id": "$_id",
            "kundennummer": "$kundennummer",
            "passwort": "$passwort",
            "status":"$status",
            "onlinestatus":"$onlinestatus",
            "kontakt":"$kontakt" 
        },
        thing: { $push: { thing_id: "$thing.thing_id", onlinestatus: "$thing.onlinestatus", status: "$thing.status",site:"$thing.site",refs: "$thing.refs" } }
    }
}

])

结果将如下所示:

{
"_id" : {
    "_id" : ObjectId("5c9bea89f4fe8c37175ade58"),
    "kundennummer" : "000001",
    "passwort" : "xxx",
    "status" : "1",
    "onlinestatus" : true,
    "kontakt" : {
        "email" : "test@test.net"
    }
},
"thing" : [
    {
        "thing_id" : 2,
        "onlinestatus" : false,
        "status" : true,
        "site" : {
            "site_id" : ObjectId("5caf395e512ab5123bb4b0af"),
            "status" : true,
            "siteName" : "Moto"
        },
        "refs" : {
            "thing_id" : ObjectId("5cb042ea512ab5123bb4b0b0"),
            "status" : true,
            "siteName" : "hi"
        }
    },
    {
        "thing_id" : 2,
        "onlinestatus" : false,
        "status" : true,
        "site" : {
            "site_id" : ObjectId("5caf395e512ab5123bb4b0af"),
            "status" : true,
            "siteName" : "Moto"
        },
        "refs" : {
            "thing_id" : ObjectId("5cb042ea512ab5123bb4b0b1"),
            "status" : true,
            "siteName" : "world"
        }
    },
    {
        "thing_id" : 2,
        "onlinestatus" : false,
        "status" : true,
        "site" : {
            "site_id" : ObjectId("5caf395e512ab5123bb4b0ae"),
            "status" : true,
            "siteName" : "hello"
        },
        "refs" : {
            "thing_id" : ObjectId("5cb042ea512ab5123bb4b0b0"),
            "status" : true,
            "siteName" : "hi"
        }
    },
    {
        "thing_id" : 2,
        "onlinestatus" : false,
        "status" : true,
        "site" : {
            "site_id" : ObjectId("5caf395e512ab5123bb4b0ae"),
            "status" : true,
            "siteName" : "hello"
        },
        "refs" : {
            "thing_id" : ObjectId("5cb042ea512ab5123bb4b0b1"),
            "status" : true,
            "siteName" : "world"
        }
    }
]

}

结果接近您想要的结果,我认为您不应该遵循这样的模式,它会使您的每个查询更加复杂。