繁体   English   中英

如何计算有条件的子文档数量

[英]How to count number of subdocuments with condition

我有一个mongoDB集合,其中包含像下面这样的文档。 我想对所有文档进行累积计数,以计算事件字段具有多少个子文档,这不是null。

{
    name: "name1",
    events: {
        created: {
            timestamp: 1512477520951
        },
        edited: {
            timestamp: 1512638551022
        },
        deleted: null
    }
}



{
    name: "name2",
    events: {
        created: {
            timestamp: 1512649915779
        },
        edited: null,
        deleted: null
    }
}

因此,对这两个文档的查询结果应返回3,因为集合中存在3个不为null的事件。 我无法更改文档的格式以使事件字段为数组。

您希望MongoDB 3.4.7或更高版本中的$objectToArray可以作为聚合语句来执行:

db.collection.aggregate([
  { "$group": {
    "_id": null,
    "total": {
      "$sum": {
        "$size": {
          "$filter": {
            "input": {
              "$objectToArray": "$events"
            },
            "cond": { "$ne": [ "$$this.v", null ] }
          }
        }
      }
    }
  }}
])

该部分需要查看"events"对象,并将每个“键/值”对转换为数组条目。 这样,您可以应用$filter操作以删除null “值”( "v"属性),然后使用$size来计算匹配列表。

所有这些都是在$group管道阶段使用$sum累加器完成的

或者,如果没有支持的版本,则需要mapReduce和JavaScript执行才能执行相同的“对象到数组”操作:

db.collection.mapReduce(
  function() {
    emit(null,
      Object.keys(this.events).filter(k => this.events[k] != null).length);
  },
  function(key,values) {
    return Array.sum(values);
  },
  { out: { inline: 1 } }
)

这通过获取对象键作为数组并拒绝那些发现其null的对象键,然后使用得到的数组的length来使用相同的基本过程。

由于使用了JavaScript评估,因此这比聚合框架的同行要慢得多。 但这实际上是您可以使用哪种服务器版本来支持所需内容的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM