如何使用猫鼬分组/聚合?

时间:2019-02-01 03:55:59

标签: javascript node.js mongodb mongoose

我的数据库充满了类似于书籍的数据对象。这也适用于书籍版本,因此,如果书籍A已被印刷9次,则我的数据库中有9个示例。这9个示例之间的联系是它们有一个ID,例如import module。在我的搜索结果中,我想舍弃所有具有相同book_id的结果,但其中一个是最近的book_id。问题是,我不确定如何使聚合正常工作。这是我现在拥有的:

published_date

第一个匹配项只是做正常的匹配项,例如按作者或流派或其他内容进行搜索。我的印象是return Book.aggregate([ { $match: generateMLabQuery(rawQuery) }, { $group: { _id: '$book_id' } }, 然后将通过唯一的$group压缩所有结果,但事实并非如此,因为我返回的只是一个看起来像book_id的项目数组。如何获取完整的Book文档,但所有旧版本都被丢弃?

2 个答案:

答案 0 :(得分:1)

由于这些书籍之间的链接为'book_id',因此很明显,您需要按'book_id'字段进行分组,这意味着对于每个'book_id',您都将获得一系列书籍。

return Book.aggregate([
    { $match: generateMLabQuery(rawQuery) },
    {
        $group: {
            _id: "$book_id",
            books: {
                $push: "$$ROOT"
            }
        }
    }
])

以上内容将为您提供有关books字段中每个book_id的文档数组。

但是每个book_id只需要一本书,并且该书必须是具有最新“ published_date”的书,因此,如果您根据“ published_date”以降序对结果进行排序,则只能获取第一个对象每次阵列的数量。

return Book.aggregate([
    { $match: generateMLabQuery(rawQuery) },
    {
        $sort: {
            "published_date": -1
        }
    },
    {
        $group: {
            _id: "$book_id",
            books: {
                $first: "$$ROOT"
            }
        }
    }
])

答案 1 :(得分:0)

组创建新对象;您可以操纵$first / $last的累加器运算符来消化所需的字段,然后$project对其进行操作:

return Book.aggregate([
  { $match: generateMLabQuery(rawQuery) },
  { 
    $group: {
      _id: '$book_id',
      published_date: { $last: '$published_date' },
      title: { $first: '$title' },
      author: { $first: '$author' }
    }
  },
  {
    $project: {
      _id: '$id',
      book_id: '$_id',
      published_date: 1,
      title: 1,
      author: 1
    }
  }
])