$lookup 与深度嵌套的对象
Posted
技术标签:
【中文标题】$lookup 与深度嵌套的对象【英文标题】:$lookup with deeply nested object 【发布时间】:2018-11-30 23:29:12 【问题描述】:我是 MongoDB 的新手,目前正在为学校开发一款建议饮食计划的食谱应用程序。因此,我需要将用户饮食计划(集合“用户”)中的“膳食”ObjectId 与集合“膳食”中的 ObjectId 结合起来。
之后,我需要在“Meals”集合中加入一个“ingredient”ObjectID,并在“Ingredients”集合中加入“ingredient”的ID。问题是,集合“Meals”中的“成分”ObjectID 位于具有另一个整数变量“amount”的对象中。该对象嵌套在一个名为“ingredients”的数组中,其中包含许多对象,例如刚刚描述的对象。
下面是我的结构:
用户
"_id": ObjectId("5b28cab902f28e18b863bd36"),
"username: "testUser1",
"password": "$2a$08$KjddpaSQPjp6aF/gseOhVeddYdqWJCJ4DpFwxfNgsk81G.0TOtN5i",
"dietPlans": Object
"dietPlanCurrent":Object
"monday":Object
"breakfast":Object
"meal": ObjectId("5b2b9a8bbda339352cc39ec4")
,
…
,
…
,
…
,
膳食
"_id" : ObjectId("5b2b9a8bbda339352cc39ec4"),
"name": "Gulasch-breakfast",
"cuisine": "International",
"ingredients":[
"ingredient": ObjectId("5b1ec0f939b55efcd4e28a2d"),
"amount": 20
,
"ingredient": ObjectId("5b1ec42474fc1f58d84264d4"),
"amount": 20
,
"ingredient": ObjectId("5b1ec42474fc1f58d84264d5"),
"amount": 20
,
…
],
"comments": [
…
]
成分
"_id": ObjectId("5b1ec0f939b55efcd4e28a2d"),
"name": "Walnut",
"calories": 654
…
"_id": ObjectId("5b1ec0f939b55efcd4e28a3d"),
"name": "Apple",
"calories": 123
…
…
我想要得到的是:
"_id": ObjectId("5b28cab902f28e18b863bd36"),
"username: "testUser1",
"password": "$2a$08$KjddpaSQPjp6aF/gseOhVeddYdqWJCJ4DpFwxfNgsk81G.0TOtN5i",
"dietPlans": Object
"dietPlanCurrent":Object
"Monday":Object
"breakfast":Object
"meal": ObjectId("5b2b9a8bbda339352cc39ec4")
"matchedIngredients": [
"_id": ObjectId("5b1ec0f939b55efcd4e28a2d"),
"name": "Walnut",
"calories": 654
…
…
]
,
…
,
…
,
…
,
我的方法不起作用(只返回空的matchedIngredients Array)
$match:
'_id': mongoose.Types.ObjectId(req.params.userId)
,
$lookup:
from: 'meals',
localField: 'dietPlans.dietPlanCurrent.monday.breakfast.meal',
foreignField: '_id',
as: "dietPlans.dietPlanCurrent.monday.breakfast.mealObject"
,
$unwind:
path: "$dietPlans.dietPlanCurrent.monday.breakfast.mealObject",
preserveNullAndEmptyArrays: true
,
$unwind:
path: "$dietPlans.dietPlanCurrent.monday.breakfast.mealObject.ingredients",
preserveNullAndEmptyArrays: true
,
$lookup:
from: 'ingredients',
localField: 'dietPlans.dietPlanCurrent.monday.breakfast.mealObject.ingredients.ingredient',
foreignField: '_id',
as: "dietPlans.dietPlanCurrent.monday.breakfast.matchedIngredients"
非常感谢您的帮助。我已经检查过这种方法,但不知何故不起作用:
Approach that didn't work for me
非常感谢!
【问题讨论】:
你的mongodb版本是多少? 【参考方案1】:mongodb 版本 3.4 无法实现您想要做的事情,但如果您升级到 3.6,那么您可以尝试以下聚合
db.collection.aggregate([
"$match": "_id": mongoose.Types.ObjectId(req.params.userId) ,
"$lookup":
"from": Meals.collection.name,
"let": "meal_id": "$dietPlans.dietPlanCurrent.monday.breakfast.meal" ,
"pipeline": [
"$match": "$expr": "$eq": [ "$_id", "$$meal_id" ] ,
"$unwind": "$ingredients" ,
"$lookup":
"from": Ingredients.collection.name,
"let": "ingredient_id": "$ingredients.ingredient" ,
"pipeline": [
"$match": "$expr": "$eq": [ "$_id", "$$ingredient_id" ]
],
"as": "matchedIngredients"
,
"$unwind": "$ingredients.matchedIngredients" ,
"$group":
"_id": "$_id",
"name": "$first":"$name" ,
"cuisine": "$first":"$cuisine" ,
"ingredients": "$push":"$ingredients"
],
"as": "dietPlans.dietPlanCurrent.monday.breakfast.mealObject"
,
"$unwind": "$dietPlans.dietPlanCurrent.monday.breakfast.mealObject"
])
【讨论】:
如果您能解决这样的相关问题,请提供帮助:***.com/questions/61109179/… @newdeveloper 当然我会做......这是晚上会在早上做 提前致谢!以上是关于$lookup 与深度嵌套的对象的主要内容,如果未能解决你的问题,请参考以下文章