首页 > 解决方案 > MongoDB - 通过将一个集合中的对象嵌套到另一个集合的对象数组中来聚合两个数组

问题描述

我正在尝试正确编写一个查询,该查询将连接来自两个集合的对象。例如,在一个集合 (A) 中,我有带有字段和用户数组的对象,每个用户对象都有 userDetailsId,我将在加入/合并每个用户和他的每个 userDetails 时使用它集合 B。

集合 A:

{
    "_id": "1",
    "field1": "value1",
    "field2": "value2",
    "users": [
        {
            "userField1": "value3",
            "userField2": "value4",
            "userDetailsId": "100"
        },{
            "userField1": "value5",
            "userField2": "value6",
            "userDetailsId": "200"
        }
    ]
}

集合 B:

{
    "_id": "100",
    "field1": "value1",
    "field2": "value2",
    "object1": {
        "field3": "value3",
        "field4": "value4"
    },
    "object2": {
        "field5": "value5",
        "field6": "value6"
    }
},
{
    "_id": "200",
    "field1": "value1",
    "field2": "value2",
    "object1": {
        "field3": "value3",
        "field4": "value4"
    },
    "object2": {
        "field5": "value5",
        "field6": "value6"
    }
}

首选结果:

{
    "_id": "1",
    "field1": "value1",
    "field2": "value2",
    "users": [
        {
            "userField1": "value3",
            "userField2": "value4",
            "userDetailsId": "100",
            "userDetails":{
                "_id": "100",
                "field1": "value1",
                "field2": "value2",
                "object1": {
                    "field3": "value3",
                    "field4": "value4"
                },
                "object2": {
                    "field5": "value5",
                    "field6": "value6"
                }
            }
        },{
            "userField1": "value5",
            "userField2": "value6",
            "userDetailsId": "200",
            "userDetails":{
                "_id": "200",
                "field1": "value1",
                "field2": "value2",
                "object1": {
                    "field3": "value3",
                    "field4": "value4"
                },
                "object2": {
                    "field5": "value5",
                    "field6": "value6"
                }
            }
        }
    ]
}

我写的查询之一,但没有得到首选的结果:

db.collectiona.aggregate([{$match: {'_id':1}},{$lookup:{from:"collectionb", localField: "users.userdetailsid", foreignField: "_id", as:"userdetails"}}

如果我运行它,我将合并这两个集合,并将集合 B 中所有匹配的 userdetails 对象作为 userdetails 数组包含在结果中。

由于我的目标是将用户及其用户详细信息合并到用户对象中,因此我尝试将其设置为:“users.userdetails”,但这将用用户详细信息数据替换用户(还没有找到一种可能的方法将 upsert 设置为 true 并添加整个匹配 userdetailsid 时用户中的 userdetails 对象)。

之后,我尝试管道聚合的结果,并尝试将 userdetails 放入带有查询的用户对象中

db.collectiona.aggregate([{$match: {'_id':1}},{$lookup:{from:"collectionb", localField: "users.userdetailsid", foreignField: "_id", as:"userdetails"},
{"$addFields":{
    "user.userdetails":{
        "$map":{
            "input": "$shifts",
            "in":{
                "$mergeObjects":["$$this",{"$arrayElemAt":["$collectionb",{"$indexOfArray":["$collectionb.id","$$this.userdetailsid"]}]}]
                }
            }
        }
    }}
}

但这也不好。

你有什么想法我怎么能正确地编写查询来获得这种结果?

标签: mongodbmongodb-queryaggregation-framework

解决方案


您需要首先$unwindusers数组与正确的数组匹配,然后userDetailsId再将用户回滚到数组中$group$push

db.collectiona.aggregate([
  { "$match": { "_id": 1 }},
  { "$unwind": "$users" },
  { "$lookup": {
    "from": "collectionb",
    "localField": "users.userDetailsId",
    "foreignField": "_id",
    "as": "users.userDetails"
  }},
  { "$unwind": "$users.userDetails" },
  { "$group": {
    "_id": "$_id",
    "field1": { "$first": "field1" }
    "field2": { "$first": "field2" }
    "users": { "$push": "users" }
  }}
])

推荐阅读