根据 child 个文档的分数排序 mongo collection

sort mongo collection based on the score of child documents

我有两个 collection,编辑和书籍。每本书都与编辑器的 parentId 字段相关联,每本书都有一个分数(比如 1、2、3)和一个类型(sci-fi、浪漫史等...)。

编辑:

{ _id: 1, name: "editor1" }
{ _id: 2, name: "editor2" }
...

和书

{ _id: 1, name: "book1", score: 1, parentId: 1, type: "sci-fi" }
{ _id: 2, name: "book2", score: 3, parentId: 1, type: "romance" }

{ _id: n, name: "bookn", score: 1, parentId: m, type: "detective" }

我想编写一个聚合,根据与之关联的所有书籍的分数对编辑器进行排序,并可选择根据书籍类型进行排序。

所以我可以检索 sci-fi 的前 10 位编辑最流行的书,或者只检索前 10 位最流行的书的编辑,而不考虑类别。

收获?使用 mongo 3.2 。我有一个强烈的印象,即 3.4 和 3.6 是可能的(我很想看看如何实现),但目前,我运送的产品是 mongo 3.2,我无法更改那...

汇总编辑 collection,我尝试先查找编辑的所有书籍,然后展开,按 parentId 分组并创建一个新的字段得分,其中包含所有书籍的得分总和在这个组中,但后来我一直在尝试使用这个分数将其与编辑相关联并最终对结果进行排序。

我在 meteor 订阅中使用这个聚合。

尝试以下聚合:

db.Editors.aggregate([
    {
        $lookup: {
            from: "Books",
            localField: "_id",
            foreignField: "parentId",
            as: "books"
        }
    },
    {
        $unwind: "$books"
    },
    {
        $group: {
            _id: "_id",
            name: { $first: "$name" },
            types: { $addToSet: "$books.type" },
            totalScore: { $sum: "$books.score" }
        }
    },
    {
        $match: { "types": "sci-fi" }
    },
    {
        $sort: { "totalScore": -1 }
    }
])

$match 阶段的一次捕获。您可以在 $group 之前使用它来计算 sci-fi books 或在 $group 之后计算所有书籍的分数但仅获得那些作者至少有一本 sci-fi 本书(如我的回答)

您可以尝试以下聚合。

So i can retrieve the first 10 editors of sci-fi with the most popular books

db.editors.aggregate([
  {"$lookup":{
    "from":"books",
    "localField":"_id",
    "foreignField":"parentId",
    "as":"books"
  }},
  {"$unwind":"$books"},
  {"$match":{"books.type":"sci-fi"}},
  {"$group":{
    "_id":"$_id",
    "name":{"$first":"$name"},
    "scores":{"$sum":"$books.score"}
  }},
  {"$sort":{"scores":-1}},
  {"$limit":10}
])

or just the first 10 editors with the most popular books regardless of categories.

db.editors.aggregate([
  {"$lookup":{
    "from":"books",
    "localField":"_id",
    "foreignField":"parentId",
    "as":"books"
  }},
  {"$project":{
    "name":1,
    "scores":{"$sum":"$books.score"}
  }},
  {"$sort":{"scores":-1}}
])