从 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 对象,而只是将其作为一个具有idnamebookmarks 的对象?

以上是关于从 mongodb 聚合中获取深层嵌套数组并包含在结果中的主要内容,如果未能解决你的问题,请参考以下文章

如何在 mongodb 聚合中展开嵌套对象数组?

如何从 1 分钟的嵌套数组数据中聚合 OHLC 5 分钟(mongodb、mongoose)

MongoDB Mongoose 聚合查询深度嵌套数组删除空结果并填充引用

如何从mongodb中的嵌套数组中获取值

从Mongo DB嵌套数组中获取不同的值并输出到单个数组

在 MongoDB 中聚合双嵌套数组的文档