2014-10-21 108 views
0

我想聚合一個給定類型的集合。如果類型爲我想組由現場筆者,如果類型爲酒吧我想按用戶MongoDb聚合和根據值取決於兩個字段的組

所有這些應該發生在一個查詢中。

實施例的數據:如果類型爲酒吧

{ 
    "_id": 1, 
    "author": { 
    "someField": "abc", 
    }, 
    "type": "foo" 
} 

{ 
    "_id": 2, 
    "author": { 
    "someField": "abc", 
    }, 
    "type": "foo" 
} 

{ 
    "_id": 3, 
    "user": { 
    "someField": "abc", 
    }, 
    "type": "bar" 
} 

該用戶字段只現有。

所以基本上就是這樣......試圖用$or來表達它。

function() { 
var results = db.vote.aggregate([ 
    { $or: [ { 

     { $match : { type : "foo" } }, 
     { $group : { _id : "$author", sumAuthor : {$sum : 1} } } }, 

     { { $match : { type : "bar" } }, 
     { $group : { _id : "$user", sumUser : {$sum : 1} } } 
    } ] } 
]); 
return results; 
} 

有人對此有一個很好的解決方案嗎?

回答

1

我認爲它可以通過

db.c.aggregate([{ 
    $group : { 
     _id : { 
      $cond : [{ 
       $eq : [ "$type", "foo"] 
      }, "author", "user"] 
     }, 
     sum : { 
      $sum : 1 
     } 
    } 
}]); 
0

下面的解決方案可以清理有點...

爲「條」(注:「富」,你必須改變一點)

db.vote.aggregate(
     { 
      $project:{ 
       user:{ $ifNull: ["$user", "notbar"]}, 
       type:1 
      } 
     }, 
     { 
      $group:{ 
       _id:{_id:"$user.someField"}, 
       sumUser:{$sum:1} 
      } 
     } 
    ) 

還要注意:在你最終的答案,任何類型爲「欄」不將有一個_id = NULL

0
完成

這裏你想要的是$cond運算符,它是一個三元運算符,在條件爲真或假的情況下返回特定值。

db.vote.aggregate([ 
    { "$group": { 
     "_id": null, 
     "sumUser": { 
      "$sum": { 
       "$cond": [ { "$eq": [ "$type", "user" ] }, 1, 0 ] 
      } 
     }, 
     "sumAuhtor": { 
      "$sum": { 
       "$cond": [ { "$eq": [ "$type", "auhtor" ] }, 1, 0 ] 
      } 
     } 
    }} 
]) 

這基本上測試當前文檔的「類型」和決定是否或者10傳遞給$sum操作。

如果「用戶」和「作者」字段包含與您的示例中相同的值,這也可以避免錯誤分組。最終結果是具有兩種類型計數的單個文檔。

+0

不是我所需要的。我需要每個作者的文檔。用戶與他們的總和 – koengsen 2014-10-22 06:45:59

+0

@koengsen足夠。我主要是看你的樣本,根據所提供的數據只能得到一份文件。這和你似乎在要求總數。 – 2014-10-22 08:24:24