2017-04-22 93 views
1

我的用戶採集文件就像下面的數組總量:獲取所有文件

{ 
    "_id" : ObjectId("58ca3a856d13601f9a474dca"), 
    "name" : "user A", 
    "email" : "[email protected]", 
    "transaction" : [ 
     { 
      "amount" : 50, 
      "type" : "CASH" 
     } 
    ] 
}, 

{ 
    "_id" : ObjectId("58ca3a856d13601f9a474dcb"), 
    "name" : "user B", 
    "email" : "[email protected]", 
    "transaction" : [ 
     { 
      "amount" : 100, 
      "type" : "CHEQUE" 
     }, 
     { 
      "amount" : 200, 
      "type" : "CASH" 
     }, 
     { 
      "amount" : -20, 
      "type" : "USED_SERVICE" 
     } 
    ] 
}, 

{ 
    "_id" : ObjectId("58ca3a856d13601f9a474dcc"), 
    "name" : "user C", 
    "email" : "[email protected]", 
    "transaction" : [ 
     { 
      "amount" : 20, 
      "type" : "CASH" 
     }, 
     { 
      "amount" : -5, 
      "type" : "USED_SERVICE" 
     }   
    ] 
} 

我需要與像現金或支票類型加起來所有用戶的所有交易。

我試過$ sum聚合算子,但仍然不知道如何得到它的作品。

https://docs.mongodb.com/manual/reference/operator/aggregation/sum/

回答

2
db.user.aggregate(
    {$unwind: "$transaction"}, 
    {$match: {"transaction.type": {$in: ["CASH", "CHEQUE"]}}}, 
    {$group: {_id: "total", sum: {$sum: "$transaction.amount"}}} 
) 
  1. 首先unwind交易陣列
  2. 然後,match由交易類型(一個或多個)
  3. 最後,group所有交易,求和它們的量
+0

嚇壞真棒 –

-1

做到這一點的最佳方式實際上是在MongoDB 3.4或更新的版本中。 此版本的mongod提供了$reduce運算符,它允許我們將$sum運算符應用於「類型」爲「CASH」或「CHECK」的「數量」值的數組。

但首先您需要通過$filter計算該數組,並使用數組運算符返回「數量」值。

$filter中的「cond」表達式也是簡單的$in表達式,在3.4版中也是新的。

當然要獲得總集合中的所有文件,你需要做到這一點的$group階段和使用null或任何等價物是在你的編程語言爲_id值。

db.collection.aggregate([ 
    { 
     "$group": { 
      "_id": null, 
      "total": { 
      "$sum": { 
       "$reduce": { 
        "input": { 
         "$map": { 
         "input": { 
          "$filter": { 
           "input": "$transaction", 
           "as": "t", 
           "cond": { 
            "$in": [ 
            "$$t.type", 
            [ 
             "CASH", 
             "CHEQUE" 
            ] 
            ] 
           } 
          } 
         }, 
         "as": "elt", 
         "in": "$$elt.amount" 
         } 
        }, 
        "initialValue": 0, 
        "in": { 
         "$add": [ 
         "$$value", 
         "$$this" 
         ] 
        } 
       } 
      } 
      } 
     } 
    } 
]) 

另一個不太有效的替代,如果你的mongod版本是3.2是$filter使用$setIsSubset操作員在「COND」表達的「交易」的數組。

從那裏,你計算「量」值的總和另一$project階段和最後階段$group返回總與$sum所有文件。

db.collection.aggregate([ 
    { 
     "$project": { 
     "transaction": { 
      "$filter": { 
       "input": "$transaction", 
       "as": "t", 
       "cond": { 
        "$setIsSubset": [ 
        [ 
         "$$t.type" 
        ], 
        [ 
         "CASH", 
         "CHEQUE" 
        ] 
        ] 
       } 
      } 
     } 
     } 
    }, 
    { 
     "$project": { 
     "amount": { 
      "$sum": "$transaction.amount" 
     } 
     } 
    }, 
    { 
     "$group": { 
     "_id": null, 
     "total": { 
      "$sum": "$amount" 
     } 
     } 
    } 
]) 
+0

InternalError該:太多的遞歸調用 –

+0

我無法重現你所得到的InternalError該。 – styvane

0

根據上述說明作爲解決它,請嘗試執行MongoDB中以下查詢殼

db.user.aggregate(

    // Pipeline 
    [ 
    // Stage 1 
    { 
     $match: { 
     transaction:{$elemMatch:{type:{$in:['CHEQUE','CASH']}}} 
     } 
    }, 

    // Stage 2 
    { 
     $unwind: {path:'$transaction'} 
    }, 

    // Stage 3 
    { 
     $group: { 
     _id:{type:'$transaction.type'}, 
     total:{$sum:'$transaction.amount'} 
     } 
    } 

    ] 


);