Mongo 使用嵌套 DBRef 查找

Mongo Lookup with nested DBRefs

我在 MongoDB 中有一个名为 'post' 的 collection,其中包含指向 'author' 的 DBRef 列表,而 DBRef 又指向 collection 'media'。

当我检索 post 时,我想获取 post 的整个 object,包括 object 中的所有作者和媒体。

例如,这是我的 collections:

post:
{
    "_id" : ObjectId("5d7db7af49c5e277395871bd"),
    "authors" : [
        DBRef("author", ObjectId("5d7daaab49c5e277395871ba")),
        DBRef("author", ObjectId("5d7daaab49c5e277395871bb"))
    ]
}

author:
[{
    "_id" : ObjectId("5d7daaab49c5e277395871ba"),
    "name" : "author 1",
    "media" : DBRef("media", ObjectId("5d7daa2049c5e277395871b8"))
},
{
    "_id" : ObjectId("5d7daaab49c5e277395871bb"),
    "name" : "author 2",
    "media" : DBRef("media", ObjectId("5d7daa2049c5e277395871b9"))
}]

media:
[{
    "_id" : ObjectId("5d7daa2049c5e277395871b8"),
    "url" : "http://image.com/1",
    "type" : "png"
},
{
    "_id" : ObjectId("5d7daa2049c5e277395871b9"),
    "url" : "http://image.com/2",
    "type" : "png"
}]

我希望得到以下查询结果:

post:
{
    "_id" : ObjectId("5d7db7af49c5e277395871bd"),
    "authors" : [
            {
                "_id" : ObjectId("5d7daaab49c5e277395871ba"),
                "name" : "author 1",
                "media" : {
                    "_id" : ObjectId("5d7daaab49c5e277395871ba"),
                    "name" : "author 1",
                    "media" : DBRef("media", ObjectId("5d7daa2049c5e277395871b8"))
                }
            },
            {
                "_id" : ObjectId("5d7daaab49c5e277395871bb"),
                "name" : "author 2",
                "media" : {
                    "_id" : ObjectId("5d7daaab49c5e277395871bb"),
                    "name" : "author 2",
                    "media" : DBRef("media", ObjectId("5d7daa2049c5e277395871b9"))
                }
            }
    ]
}

到目前为止,我有以下查询,其中包括 post 中的作者,但我需要帮助来检索作者中的媒体。

current query:

db.post.aggregate([
{
    $project: { 
        authors: {
          $map: { 
             input: { 
                  $map: {
                      input:"$authors",
                      in: {
                           $arrayElemAt: [{$objectToArray: "$$this"}, 1]
                      },
                  }
             },
             in: "$$this.v"}},
        }

}, 
{
    $lookup: {
        from:"author", 
        localField:"authors",
        foreignField:"_id", 
        as:"authors"
    }
},
])

current result:

{
    "_id" : ObjectId("5d7db7af49c5e277395871bd"),
    "authors" : [
        {
            "_id" : ObjectId("5d7daaab49c5e277395871ba"),
            "name" : "author 1",
            "media" : DBRef("media", ObjectId("5d7daa2049c5e277395871b8"))
        },
        {
            "_id" : ObjectId("5d7daaab49c5e277395871bb"),
            "name" : "author 2",
            "media" : DBRef("media", ObjectId("5d7daa2049c5e277395871b9"))
        }
    ]
}

尝试使用 $unwind 然后 $goup 通过 id

你可以这样做

db.post.aggregate([{
    $project: {
        authors: {
            $map: {
                input: {
                    $map: {
                        input: "$authors",
                        in: {
                            $arrayElemAt: [{
                                $objectToArray: "$$this"
                            }, 1]
                        },
                    }
                },
                in: "$$this.v"
            }
        },
    }
}, {
    $lookup: {
        from: "author",
        localField: "authors",
        foreignField: "_id",
        as: "authors"
    }
}, {
    $unwind: "$authors"
}, {
    $project: {
        "authors.media": {
            $arrayElemAt: [{
                $objectToArray: "$authors.media"
            }, 1]
        },
        "authors._id": 1,
        "authors.name": 1
    }
}, {
    $lookup: {
        from: "media",
        localField: "authors.media.v",
        foreignField: "_id",
        as: "authors.media"
    }
}, {
    $unwind: {
        path: "$authors.media",
        preserveNullAndEmptyArrays: true
    }
}, {
    $group: {
        _id: "$_id",
        authors: {
            $push: "$authors"
        }
    }
}]).pretty()

这是结果


    "_id" : ObjectId("5d7db7af49c5e277395871bd"),
    "authors" : [
        {
            "_id" : ObjectId("5d7daaab49c5e277395871ba"),
            "name" : "author 1",
            "media" : {
                "_id" : ObjectId("5d7daa2049c5e277395871b8"),
                "url" : "http://image.com/1",
                "type" : "png"
            }
        },
        {
            "_id" : ObjectId("5d7daaab49c5e277395871bb"),
            "name" : "author 2",
            "media" : {
                "_id" : ObjectId("5d7daa2049c5e277395871b9"),
                "url" : "http://image.com/2",
                "type" : "png"
            }
        }
    ]
}

中段$project可以换格式

还有什么
$unwind 可以与选项一起使用。以下 $unwind 操作使用 preserveNullAndEmptyArrays 选项在输出中包括那些缺少 sizes 字段、null 或空数组的文档。

[
   { $unwind: { path: "$sizes", preserveNullAndEmptyArrays: true } }
]

这里是 documents