对于以下数据集示例:
列表
{ _id: 1, included_lists: [ 2 ], items: [ "i1" ]}
{ _id: 2, included_lists: [], items: [ "i2", "i3" ]}
项目
{ _id: "i1", details: [{}, {}, {}]}
{ _id: "i2", details: [{}, {}, {}]}
{ _id: "i3", details: [{}, {}, {}]}
我想获取列表中的所有项目,包括附加在included_lists
上的项目
例如:如果我们查看列表_id
1,我们应该得到项目i1, i2, i3
我有一个方法,涉及使用populate
或$lookup
,但是我不确定如何解开items
中嵌套的included_lists
并与原始列表中的items
一起加入。
最后,我希望有一个可以使用limit
,skip
和match
的数据集。
我正在使用猫鼬,但是香草mongodb代码也可以。
更新
我目前的做法是首先在一个查询中检索所有列表ID,即
List.find({ _id: id}, { included_lists: 1})
然后使用列表ID对该数组进行数组,即
var all_ids = [id, ...included_lists]
然后只需找到物品并放松
伪代码:
List
.aggregate([
{
$match: {
_id: {
$in: all_ids
}
}
},
{ $lookup: {} }
{
$unwind: "$items"
},
{
$project: {
"list.name": 1,
"list._id": 1,
"items": 1
}
}
])
但是我不想做第一个查询来检索所有list_id,我应该能够仅通过一个_id
检索所有相关项,然后再检索其余的项。 included_lists
答案 0 :(得分:1)
您可以尝试从mongodb 3.6及更高版本进行以下聚合
List.aggregate([
{ "$match": { "_id": id }},
{ "$lookup": {
"from": Items.collection.name,
"let": { "items": "$items" },
"pipeline": [
{ "$match": { "$expr": { "$in": [ "$_id", "$$items" ] } } }
],
"as": "items"
}},
{ "$lookup": {
"from": Lists.collection.name,
"let": { "included_lists": "$included_lists", "items": "$items" },
"pipeline": [
{ "$match": { "$expr": { "$in": [ "$_id", "$$included_lists" ] } } },
{ "$lookup": {
"from": Items.collection.name,
"let": { "items": "$items" },
"pipeline": [
{ "$match": { "$expr": { "$in": [ "$_id", "$$items" ] } } }
],
"as": "items"
}},
{ "$project": { "allItems": { "$concatArrays": [ "$$items", "$items" ]}}}
],
"as": "included_lists"
}},
{ "$unwind": "$included_lists" },
{ "$replaceRoot": { "newRoot": "$included_lists" }}
])
答案 1 :(得分:1)
您可以尝试在3.4中进行以下汇总。
最初的$lookup
用于获取included_lists的项目值,然后是$concatArrays
以合并所查找的项目和项目。
第二个$lookup
获取项目详细信息,然后$unwind
统一结果。
List.aggregate([
{"$lookup":{
"from":name of the list collection,
"localField":"included_lists",
"foreignField":"_id",
"as":"included_items"
}},
{"$unwind":"$included_items"},
{"$project":{"allItems":{"$concatArrays":["$items","$included_items.items"]}}},
{"$lookup":{
"from":name of the item collection,
"localField":"allItems",
"foreignField":"_id",
"as":"lookedup_items"
}},
{"$unwind":"$lookedup_items"},
{"$skip": some number},
{"$limit": some number}
])