如何在 mongodb 聚合中展开嵌套对象数组?
Posted
技术标签:
【中文标题】如何在 mongodb 聚合中展开嵌套对象数组?【英文标题】:How to unwind nested object arrays in mongodb aggregation? 【发布时间】:2021-07-20 11:44:33 【问题描述】:我有一些包含另一个数组的对象数组的数据。我正在尝试展开 courses 数组,然后展开 requirements 数组以匹配主题,然后将所有内容组合在一起。
到目前为止,我可以很好地使用 courses 数组。但是我无法为第二个数组requirements做同样的事情。
[
"_id": 1,
"name": "provider name",
"courses": [
"_id": 1,
"name": "course name",
"requirements": [
"subjects": [
"SubjectA::B",
"SubjectB::B",
"SubjectC::B"
]
,
"subjects": [
"SubjectA::B",
"SubjectB::B",
"SubjectC::B"
]
]
]
]
首先我展开两个数组
$unwind:
path: '$courses',
preserveNullAndEmptyArrays: true
,
$unwind:
path: '$courses.requirements',
preserveNullAndEmptyArrays: true
,
我如何对第一个数组进行分组
$group:
_id: '$_id',
root: $mergeObjects: '$$ROOT' ,
courses: $push: '$courses'
,
$replaceWith:
$mergeObjects: ['$root', '$$ROOT'],
,
$project: root: 0
,
预期输出
[
"_id": 1,
"name": "provider name",
"courses": [
"_id": 1,
"name": "course name",
"requirements": [
"subjects": [
"SubjectA::B",
"SubjectB::B",
"SubjectC::B"
]
,
"subjects": [
"SubjectA::B",
"SubjectB::B",
"SubjectC::B"
]
]
]
]
但我明白了
[
"_id": 1,
"name": "provider name",
"courses": [
"_id": 1,
"name": "course name",
"requirements": [
"subjects": [
"SubjectA::B",
"SubjectB::B",
"SubjectC::B"
]
,
"subjects": [
"SubjectA::B",
"SubjectB::B",
"SubjectC::B"
]
]
,
"_id": 1,
"name": "course name",
"requirements": [
"subjects": [
"SubjectA::B",
"SubjectB::B",
"SubjectC::B"
]
,
"subjects": [
"SubjectA::B",
"SubjectB::B",
"SubjectC::B"
]
]
]
]
【问题讨论】:
添加预期输出 【参考方案1】:您可以通过以下阶段重构游览阵列,
$group
by _id
和 courses._id
并获得第一个 name
和课程名字,并构造 requirements
数组
$group
仅由 _id
得到第一个 name
并重构 courses
数组
$group:
_id:
_id: "$_id",
cId: "$courses._id"
,
name: $first: "$name" ,
course_name: $first: "$courses.name" ,
requirements: $push: "$courses.requirements"
,
$group:
_id: "$_id._id",
name: $first: "$name" ,
courses:
$push:
_id: "$_id.cId",
name: "$course_name",
requirements: "$requirements"
Playground
【讨论】:
太好了,这真的很有帮助。那么,如果我在数千条记录上运行此管道,是否会导致数据库成本高昂? 你说的高成本是什么意思?如果您在谈论性能,如果您在根目录中有更多文档,则可以,但如果您有更多嵌套文档,则会影响。 是的,表现,我的期望在前几个比赛阶段之后,每个课程数组的最终结果将少于 100 个,而需求数组中的大约 2 到 3 个。这种方法在性能方面是否可行,还是不推荐。 这会影响表现问题,但是,你能解释一下并分享你在小组赛之前做什么比赛吗?所以我将在没有放松和小组阶段的情况下分享另一个查询。所以之后你可以比较两个查询的性能。 我能理解,但你能分享一下你在 $group 阶段之前做了什么过滤吗?你能在操场上添加它并分享我新的链接。以上是关于如何在 mongodb 聚合中展开嵌套对象数组?的主要内容,如果未能解决你的问题,请参考以下文章