Arrays 嵌套对象数组上的mongoDB聚合查找
我有一个集合,它看起来如下所示,我很难执行$lookup并返回它最初的方式,但是填充了字段: 我对要填充的字段(代理、任务、客户、客户)发表了评论 结果应该是这样的:Arrays 嵌套对象数组上的mongoDB聚合查找,arrays,mongodb,mongoose,aggregation-framework,Arrays,Mongodb,Mongoose,Aggregation Framework,我有一个集合,它看起来如下所示,我很难执行$lookup并返回它最初的方式,但是填充了字段: 我对要填充的字段(代理、任务、客户、客户)发表了评论 结果应该是这样的: { "title":"Tournée libre", "agent": {firstname: 'something', lastname: 'something else'} "missions":[ { "_id":"5d8a075346f10d679ab4383e
{
"title":"Tournée libre",
"agent": {firstname: 'something', lastname: 'something else'}
"missions":[
{
"_id":"5d8a075346f10d679ab4383e",
"title":"Journée 3",
"clients":[
{
"_id":"5d8a075346f10d679ab4383f",
"valid":true,
"client": {firstname: 'something', lastname: 'something else'},
"visit_time":"2019-09-24T12:03:38.383Z"
},
{
"_id":"5d8a0dc446f10d679ab43888",
"valid":true,
"client":{firstname: 'something', lastname: 'something else'},
"visit_time":"2019-09-24T12:34:23.210Z"
},
]
}
],
"created_at":"2019-09-24T12:08:51.928Z",
"__v":2
}
您可以使用下面的聚合管道 $lookup用于填充代理,然后是$reduce和$concatarray用于收集所有客户端ID,$lookup用于获取客户端详细信息 $addFields和$map用于迭代任务数组,对于每个客户机,通过按客户机id和$mergeObjects查找来映射上一阶段的客户机信息,以保留其他字段$项目阶段以删除额外字段 Mongo db 3.6及以上版本
Model.aggregate([
{"$lookup":{
"from":"agents",
"localField":"agent",
"foreignField":"_id",
"as":"agent"
}},
{"$addFields":{"agent":{"$arrayElemAt":["$agent",0]}}},
{"$addFields":{
"client_ids":{
"$reduce":{
"input":"$missions",
"initialValue":[],
"in": {"$concatArrays":["$$value","$$this.clients.client"]}
}
}
}},
{"$lookup":{
"from":"clients",
"localField":"client_ids",
"foreignField":"_id",
"as":"client_info"
}},
{"$addFields":{
"missions":{
"$map":{
"input":"$missions",
"in":{
"$mergeObjects":[
"$$this",
{"clients":{"$map":{
"input":"$$this.clients",
"in":{"$mergeObjects":[
"$$this",
{"client":{"$arrayElemAt":[
"$client_info",
{"$indexOfArray":["$client_ids","$$this._id"]}
]}}
]}
}}}
]
}
}
}
}},
{"$project":{"client_ids":0,"client_info":0}}
])
Mongo db小于3.6
$lookup填充代理,然后$unwind到达客户端并查找以获取客户端详细信息。使用$group倒带,以使用填充的值恢复到原始结构
Model.aggregate([
{"$lookup":{
"from":"agents",
"localField":"agent",
"foreignField":"_id",
"as":"agent"
}},
{"$addFields":{"agent":{"$arrayElemAt":["$agent",0]}}},
{"$unwind":"$missions"},
{"$unwind":"$missions.clients"},
{"$lookup":{
"from":"clients",
"localField":"missions.clients.client",
"foreignField":"_id",
"as":"missions.clients.client"
}},
{"$addFields":{"missions.clients.client":{"$arrayElemAt":["$missions.clients.client",0]}}},
{"$group":{
"_id":{"_id":"$_id","mission_id":"$missions._id"},
"agent":{"$first":"$agent"},
"title":{"$first":"$missions.title"},
"clients":{"$push":"$missions.clients"}
}},
{"$group":{
"_id":"$_id._id",
"agent":{"$first":"$agent"},
"missions":{
"$push":{
"_id":"$_id.mission_id",
"title":"$title",
"clients":"$clients"
}
}
}}
])
.populate(agent missions.clients.client')给它一个tryI使用populate时遇到了性能问题,因为我正在实现分页,并且我有用户角色。这就是我想要的
Model.aggregate([
{"$lookup":{
"from":"agents",
"localField":"agent",
"foreignField":"_id",
"as":"agent"
}},
{"$addFields":{"agent":{"$arrayElemAt":["$agent",0]}}},
{"$unwind":"$missions"},
{"$unwind":"$missions.clients"},
{"$lookup":{
"from":"clients",
"localField":"missions.clients.client",
"foreignField":"_id",
"as":"missions.clients.client"
}},
{"$addFields":{"missions.clients.client":{"$arrayElemAt":["$missions.clients.client",0]}}},
{"$group":{
"_id":{"_id":"$_id","mission_id":"$missions._id"},
"agent":{"$first":"$agent"},
"title":{"$first":"$missions.title"},
"clients":{"$push":"$missions.clients"}
}},
{"$group":{
"_id":"$_id._id",
"agent":{"$first":"$agent"},
"missions":{
"$push":{
"_id":"$_id.mission_id",
"title":"$title",
"clients":"$clients"
}
}
}}
])