mongoDB对嵌套对象数组的聚合查找
Posted
技术标签:
【中文标题】mongoDB对嵌套对象数组的聚合查找【英文标题】:mongoDB aggregate lookup on nested array of objects 【发布时间】:2020-01-24 17:13:14 【问题描述】:我有一个如下所示的集合,但我无法执行 $lookup 并以最初的方式返回它,但填充字段:
我已经在我想要填充的字段上创建了 cmets(代理、missions.clients.client)
"title":"Tournée libre",
"agent":"5d811943d2a2100017667228", // needs to be populated
"missions":[
"_id":"5d8a075346f10d679ab4383e",
"title":"Journée 3",
"clients":[
"_id":"5d8a075346f10d679ab4383f",
"valid":true,
"client":"5d1bc39aa2af623b94363b33", // this needs to be populated
"visit_time":"2019-09-24T12:03:38.383Z"
,
"_id":"5d8a0dc446f10d679ab43888",
"valid":true,
"client":"5d8a0c8346f10d679ab43886",
"visit_time":"2019-09-24T12:34:23.210Z"
,
]
],
"created_at":"2019-09-24T12:08:51.928Z",
"__v":2
结果应该是这样的:
"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
【问题讨论】:
.populate(agentmissions.clients.client') 试试看 我正在使用填充,但考虑到我正在实现分页并且我有用户角色,我遇到了性能问题。所以我要的是聚合 【参考方案1】:您可以使用以下聚合管道。
$lookup 填充代理,然后 $reduce 和 $concatArrays 收集所有客户端 ID,$lookup 获取客户端详细信息。
$addFields 和 $map 来迭代任务数组,并为每个客户端通过客户端 ID 和 $mergeObjects 查找来映射前一阶段的客户端信息以保留其他字段。 $project 阶段删除多余的字段。
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"
])
【讨论】:
以上是关于mongoDB对嵌套对象数组的聚合查找的主要内容,如果未能解决你的问题,请参考以下文章