[英]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
来计算匹配列表。
或者,如果没有支持的版本,则需要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.