簡體   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