【问题标题】:Get a deep-nested array from a mongodb aggregate and include in result从 mongodb 聚合中获取深层嵌套数组并包含在结果中
【发布时间】: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()

有人能指出我正确的方向吗?谢谢!

【问题讨论】:

    标签: mongodb mongoose nosql aggregation-framework


    【解决方案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 的对象?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    • 2020-03-29
    • 2018-08-02
    • 2017-07-26
    • 2019-01-13
    • 1970-01-01
    • 2021-07-01
    相关资源
    最近更新 更多