从 mongodb 聚合中获取深层嵌套数组并包含在结果中
Posted
技术标签:
【中文标题】从 mongodb 聚合中获取深层嵌套数组并包含在结果中【英文标题】:Get a deep-nested array from a mongodb aggregate and include in result 【发布时间】:2020-01-24 08:11:32 【问题描述】:假设我有这两个系列
book:
_id: 'aaa'
name: 'Book 1',
chapters: [
0:
_id: 'chapter0',
name: 'Chapter 1',
pages: [
0:
_id: 'page0',
name: 'Page 1',
paragraphs: [
0:
_id: 'paragraph0',
name: 'Paragraph 1',
bookmarks: [
0: sentence: 3, reader: 'Foo',
1: sentence: 8, reader: 'Bar',
2: sentence: 14, reader: 'John'
]
]
]
]
book:
_id: 'bbb'
name: 'Book 2',
chapters: [
0:
_id: 'chapter0',
name: 'Chapter 1',
pages: [
0:
_id: 'page0',
name: 'Page 1',
paragraphs: [
0:
_id: 'paragraph0',
name: 'Paragraph 1',
bookmarks: []
,
1:
_id: 'paragraph1',
name: 'Paragraph 2',
bookmarks: [
0: sentence: 2, reader: 'George',
1: sentence: 1, reader: 'Paul',
2: sentence: 76, reader: 'John',
3: sentence: 54, reader: 'Ringo'
]
]
]
]
我希望能够在获得结果时提取数组bookmarks
并将它们附加到book
集合中。像这样的东西会很好:
id: 'aaa'
name: 'Book 1'
bookmarks: [..., ..., ...] //since the first book has 3 bookmarks
,
id: 'bbb'
name: 'Book 2'
bookmarks: [..., ..., ..., ...] //since the second book has 4 bookmarks
,
如果没有书签,它应该是这样的:
id: 'aaa'
name: 'Book 1'
bookmarks: [..., ..., ...] //since the first book has 3 bookmarks
,
id: 'bbb'
name: 'Book 2'
bookmarks: [..., ..., ..., ...] //since the second book has 4 bookmarks
,
id: 'ccc'
name: 'Book 3'
bookmarks: [] //third book does not have bookmarks for example
,
我已尝试使用此代码进行聚合,但它只是将每本书的每个书签分开并将其推送到对象中。
return yield Books.aggregate()
.unwind('chapters')
.unwind('chapters.pages')
.unwind('chapters.pages.paragraphs')
.unwind('chapters.pages.paragraphs.bookmarks')
.group(
_id: '$_id',
books:
$push:
_id: '$_id',
name: '$name',
bookmarks: '$chapters.pages.paragraphs.bookmarks'
).exec()
有人能指出我正确的方向吗?谢谢!
【问题讨论】:
【参考方案1】:尝试以下聚合管道:
Books.aggregate([
$unwind: "$book"
,
$unwind: "$book.chapters"
,
$unwind: "$book.chapters.pages"
,
$unwind: "$book.chapters.pages.paragraphs"
,
$unwind:
path: "$book.chapters.pages.paragraphs.bookmarks",
preserveNullAndEmptyArrays: true
,
$group:
_id:
_id: "$_id",
book: "$book.name"
,
bookmarks:
$push: "$book.chapters.pages.paragraphs.bookmarks"
])
【讨论】:
不走运,它返回的数据与我得到的数据相同,即书签一一占用结果,而不是附加到book
对象
它可以工作,但需要注意的是,如果 bookmarks
数组为空,它不会返回 book
字段。它仍应返回它,但使用bookmarks: []
。如何修改代码以获得该结果?
在最后展开时添加 preserveNullAndEmptyArrays 然后 $unwind: path: "$book.chapters.pages.paragraphs.bookmarks", preserveNullAndEmptyArrays: true ,
哦,顺便说一句,您应该编辑您的答案以反映您在此处添加的评论。但是我已经接受了
不过还有最后一期。 'bookmarks' 数组在_id
对象之外,我假设它由$group 使用。有没有办法不使用_id
对象,而只是将其作为一个具有id
、name
和bookmarks
的对象?以上是关于从 mongodb 聚合中获取深层嵌套数组并包含在结果中的主要内容,如果未能解决你的问题,请参考以下文章
如何从 1 分钟的嵌套数组数据中聚合 OHLC 5 分钟(mongodb、mongoose)