如何计算 mongo 中参考集合的不同值

How to count distinct values of a reference collection in mongo

有一个指向作者列表的书籍列表,我想显示一棵树,在每个节点中都有作者姓名和他写的书的数量。最初,我将 authors[] 数组直接嵌入到 books 集合中,这非常有效,使用了聚合框架的魔力。然而,后来,我意识到为每个作者附上一些附加信息会很好(例如照片、传记数据、出生日期等)。对于第一个解决方案,这很糟糕,因为:

接下来是使用第二个集合,称为 authors,每个 books 文档都引用作者 ID 列表,像这样:

{
    "_id" : ObjectId("58ed2a254374473fced950c1"),
    "authors" : [ 
        "58ed2a254d74s73fced950c1", 
        "58ed2a234374473fce3950c1"
    ],
    "title" : "Book title"
....
}

为了获取作者的详细信息,我有两个选择:

问题:

  1. 使用 DBRefs 自动将作者数据加载到书籍对象中,类似于 JPA @MannyToOne 所做的事?
  2. 是否可以获取每个作者的著作数量,而不必查询每个作者的书籍数量?当作者被嵌入时,我能够汇总不同的作者姓名以及他出现的书籍文档的数量。两个集合之间可以这样查询吗?

对于实施此行为,您有何建议? (我正在使用 Spring 数据)

根据@Veeram 的建议,我能够编写此查询:

db.book_collection.aggregate([
    {
        $unwind: "$authorsIds"
    },
    {
        $lookup: {
            from: "authors_collection",
            localField: "authorsIds",
            foreignField: "_id",
            as: "ref"
        }
    },
    {$group: {_id: "$ref.authorName", count: {$sum: 1}}}
])

其中 returns 是这样的:

{
    "_id" : [ 
        "Paulo Coelho"
    ],
    "count" : 1
}

/* 2 */
{
    "_id" : [ 
        "Jules Verne"
    ],
    "count" : 2
}

这正是我需要的,而且听起来不错。我现在只需要做一个额外的查询来获取没有作者集的书。

您可以在 spring mongo 应用程序中尝试以下查询。

UnwindOperation unwindAuthorIds = Aggregation.unwind("authorsIds", true);
LookupOperation lookupAuthor = Aggregation.lookup("authors_collection", "authorsIds", "_id", "ref");
UnwindOperation unwindRefs = Aggregation.unwind("ref", true);
GroupOperation groupByAuthor = Aggregation.group("ref.authorName").count().as("count");

Aggregation aggregation = Aggregation.newAggregation(unwindAuthorIds, lookupAuthor, unwindRefs, groupByAuthor);

List<BasicDBObject> results = mongoOperations.aggregate(aggregation, "book_collection", BasicDBObject.class).getMappedResults();