我有一个收藏集Items
,其中包含诸如
{
"_id": "5d9e3a5ced27230f68032e21",
... more fields
"foos": [
{
"_id": "5d9e3a5ced27230f68032e25",
... more fields
"bars": [
"5d9dab461bbb4db66db41f93"
],
},
{
"id": "5d9e3a5ced27230f68032e24",
... more fields
"bars": [
"5d9dab461bbb4db66db41f93",
"5d9e3a23ed27230f68032e1a"
]
}
]
}
,其中bars
引用了另一个集合Bars
。
我想在Items
中获得所有文档的列表(及其所有字段),但是将bars
解析为Bars
中的文档。
我希望能够创建一个通用函数,只需向其传递解析路径(例如foos.bars
)和要解析的集合(Bars
),以便我可以使用它具有不同的集合和任意级别的嵌套。
在我的示例中,我找到了一种相当复杂的方法来进行此操作,但是在我将其概括之前,我想知道是否真的没有一种更简单的方法。输入非常感谢!
这就是我所拥有的:
[
{
"$unwind": {
"path": "$foos",
"includeArrayIndex": "foos_index"
}
},
{
"$unwind": {
"path": "$foos.bars"
}
},
{
"$lookup": {
"from": "Bars",
"localField": "foos.bars",
"foreignField": "_id",
"as": "foos.bars"
}
},
{
"$unwind": {
"path": "$foos.bars"
}
},
{
"$group": {
"_id": {
"id": "$_id",
"foo_index": "$foos_index"
},
"foos": {
"$first": "$foos"
},
"bars": {
"$push": "$foos.bars"
}
}
},
{
"$addFields": {
"foos": {
"$mergeObjects": [
"$foos",
{
"bars": "$bars"
}
]
}
}
},
{
"$group": {
"_id": "$_id.id",
"foos": {
"$push": "$foos"
}
}
},
{
"$lookup": {
"from": "Items",
"localField": "_id",
"foreignField": "_id",
"as": "original_doc"
}
},
{
"$unwind": {
"path": "$original_doc"
}
},
{
"$replaceRoot": {
"newRoot": {
"$mergeObjects": [
"$original_doc",
{
"foos": "$foos"
}
]
}
}
}
]
我已经意识到我不需要解开“叶子”级,所以现在有了简化版本(但是对于更深层的嵌套,我仍然需要以前的版本,对吧?):>
[
{
"$unwind": {
"path": "$foos",
"includeArrayIndex": "foos_index"
}
},
{
"$lookup": {
"from": "Bars",
"localField": "foos.bars",
"foreignField": "_id",
"as": "foos.bars"
}
},
{
"$group": {
"_id": "$_id",
"foos": {
"$push": "$foos"
}
}
},
{
"$lookup": {
"from": "Items",
"localField": "_id",
"foreignField": "_id",
"as": "original_doc"
}
},
{
"$unwind": {
"path": "$original_doc"
}
},
{
"$replaceRoot": {
"newRoot": {
"$mergeObjects": [
"$original_doc",
{
"foos": "$foos"
}
]
}
}
}
]
答案 0 :(得分:0)
也许有人仍然发现更好的东西,但是直到那时,如果有人遇到了这个问题,那么现在对我来说,以下几点似乎是合理的:
[
{
"$unwind": {
"path": "$foos",
"includeArrayIndex": "foos_index"
}
},
{
"$lookup": {
"from": "Bars",
"localField": "foos.bars",
"foreignField": "_id",
"as": "foos.bars"
}
},
{
"$group": {
"_id": "$_id",
"savepoint": {
"$first": "$$ROOT"
},
"foos": {
"$push": "$foos"
}
}
},
{
"$replaceRoot": {
"newRoot": {
"$mergeObjects": [
"$savepoint",
{
"foos": "$foos"
}
]
}
}
}
]