目前,我在MongoDB中有很多文档.我需要做的是找到每个唯一的字段、关键字和值,并计算每个字段、关键字和值的总数量. 例如,如果我们有以下文档:

[{ value1: 'same', value2: 'unique'}, { value1: 'same', value2: 'unique1' }, { value3: 'new' }] 

输出应该是(大致如此--确切的格式无关紧要)

[
    {
        value1: { 
            same: 2, // there are 2 documents with { value1: 'same' }
        },
        value2: {
            unique: 1, // there is 1 document with { value2: 'unique' }
            unique1: 1, // there is 1 document with { value2: 'unique1' }
        },
        value3: {
            new: 1, // there is 1 document with { value3: 'new' }
        },
    }
]

我不确定是否有一种好的、高性能的方法来实现这一点(我们可以对所有属性进行"展开",但这将 for each 属性创建一个新文档,然后循环遍历每个属性,这将对性能造成极大的影响)

我有两种方法似乎非常接近于让一个大致的 idea 奏效,但我对这两种方法都有意见.

  1. $Function+全局变量.

如果我可以遍历每个文档并使用一个全局"输出"变量,我就可以简单地 for each 文档更新该变量,在JS中完成工作,然后在最后返回该变量.

我试图为此做的"概念证明"将是简单地递增一个全局变量,然后将该变量作为文档返回.

[{
    // write a custom JS function that has access to the current document
    $replaceRoot: {
        newRoot: {
            $function: {
                body: function (doc: any, TOTAL_COUNT: any) {
                    if (!TOTAL_COUNT) TOTAL_COUNT = 0; // set the initial value
                    TOTAL_COUNT++; // this doesn't truly increment the "$TOTAL_COUNT" variable :(
                    return { total_count: TOTAL_COUNT };
                },
                args: ['$$ROOT', '$TOTAL_COUNT'],
                lang: 'js',
            },
        },
    },
},
]
  1. 累加器

我非常确定这样做的"正确"方法是使用累加器(因为它们是用来存储持久信息的).但是,可用于累加器的方法只有$group、$Bucket和$BucketAuto.

就我所知,这些都不允许我简单地"返回输出",类似于$PROJECT或$replaceRoot.

我很乐意使用累加器或函数,一旦我的概念证明有效,我将自己完成其余的工作:)

谢谢你的任何帮助/建议!非常感谢:)

推荐答案

您可以首先将文档转换为k-v元组的array.$unwind个数组,根据需要 Select $group个.

db.collection.aggregate([
  {
    "$project": {
      kv: {
        "$objectToArray": "$$ROOT"
      }
    }
  },
  {
    "$unwind": "$kv"
  },
  {
    "$match": {
      "kv.k": {
        $ne: "_id"
      }
    }
  },
  {
    $group: {
      _id: {
        k: "$kv.k",
        v: "$kv.v"
      },
      cnt: {
        $sum: 1
      }
    }
  }
])

这是Mongo Playground元,供您参考.

Mongodb相关问答推荐

如何使用MongoDB对子文档进行条件投影?

MongoDB/Mongoose查询:使用优先约束检索从位置A到位置B的路径

在MongoDB Aggregate for My BooksDB中将`$match`放在`$unwin`之前或之后的区别

MongoDB:如何获取多个$indexOfArray值?

如何通过 Go 以 UUID 类型保存 Mongo 中的内容?

从 MongoDB 中的聚合结果中获取不同的值

可变用户 Select

在mongodb中,如何使用聚合来获取字段之间的对应关系

将子文档中的所有字段设置为 false,然后在单个查询中将第二个字段设置为 true

MongoDB:插入重复键更新

Express 无法 PUT/DELETE 方法.出了什么问题?

在 mongodb 中查找字段的所有非不同值

使用 mongoimport 将日期(ISODate)导入 MongoDB

在 Postgres JSON 数组中查询

为什么使用 Redis 而不是 MongoDb 进行缓存?

在 mongodb 聚合框架中执行 case-statement

Mongoimport json 文件更新或覆盖..?

MongoDB:如何在 100 个集合中找到 10 个随机文档?

使用 MongoDB 的 map/reduce 来分组两个字段

如何在mongoose的嵌套填充中 Select 特定字段