mongodb - 按数组对文档进行分组,将数组视为一个集合

标签 mongodb mongodb-query aggregation-framework

我有一个听起来相当简单的任务,我想使用 MongoDB 的聚合管道来实现。我想将一个字段中的数组视为集合(即,忽略顺序和重复),并按它们进行分组。例如,该集合可能是:

[
    {
        _id: 1
        names: ["a", "b"]
    },
    {
        _id: 2
        names: ["c", "a"]
    },
    {
        _id: 3
        names: ["b", "a"]
    }
]

我想要返回的结果是这样的:

[
    {
        names: ["a", "b"],
        count: 2
    },
    {
        names: ["a", "c"],
        count: 1
    }
]

谢谢!

最佳答案

您需要$sort结果使它们对于分组键一致。确实没有其他办法:

db.collection.aggregate([
    { "$unwind": "$names" },
    { "$sort": { "_id": 1, "names": 1} },
    { "$group": {
        "_id": "$_id",
        "names": { "$push": "$names" }
    }},
    { "$group": {
        "_id": "$names",
        "count": { "$sum": 1 }
    }}
])

按照您的要求返回:

[
    {
        "_id": ["a", "b"],
        "count": 2
    },
    {
        "_id": ["a", "c"],
        "count": 1
    }
]

虽然有很多像“集合”这样的数组操作符,但它们都没有将数组内容“重新排序”为分组时适用的一致方式。仅当您 $sort 时才会完成此操作。

即使数组包含“重复项”,并且应用了一些集合转换,它们的顺序仍然不一致:

db.testa.insert_many([
    { "a" : [ "a", "b" ] },
    { "a" : [ "b", "a" ] },
    { "a" : [ "b", "a", "a" ] }
])

db.testa.aggregate({ "$project": { "_id": 0, "a": { "$setUnion": [ "$a", [] ] } } })

该示例当然会返回:

{ "a" : [ "b", "a" ] }
{ "a" : [ "a", "b" ] }
{ "a" : [ "a", "b" ] }

因此,您“仍然”需要 $unwind$sort 以获得用于分组目的的一致“集”。

关于mongodb - 按数组对文档进行分组,将数组视为一个集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36213762/

相关文章:

javascript - 如何按条件查询具有最新日期的子文档

MongoDB/Mongoose 对日期字段的唯一约束

mongodb - 查询以检索 mongodb 数组中的多个对象

MongoDB - 检查对象数组中是否存在键

spring - Spring-MongoDb聚合框架中如何使用$cond操作

c# - 在带有自定义 poco 对象作为 id 的 mongodb 文档中查找

node.js - 具有 2 个集合的 Mongodb 聚合

mongodb - 在 ansible playbook for mongodb 中出现 rs.add() 问题

node.js - FindOne 与 MongooseJS 然后提前存储结果?

mongodb - 为什么mongodb不使用全索引