你基本上要$cond
選擇是否通過1
或0
到$sum
累加器在$group
管道,和一個初始值「陣列」使用$unwind
創造每個人的文件的副本兩個領域。
db.data.aggregate([
{ "$addFields": {
"val": ["$installer","$tester"]
}},
{ "$unwind": "$val" },
{ "$group": {
"_id": { "_id": "$_id", "val": "$val" },
"installer": {
"$max": {
"$cond": [
{ "$eq": ["$installer","$val"] },
1,
0
]
}
},
"tester": {
"$max": {
"$cond": [
{ "$eq": ["$tester","$val"] },
1,
0
]
}
}
}},
{ "$group": {
"_id": "$_id.val",
"installer": { "$sum": "$installer" },
"tester": { "$sum": "$tester" }
}}
])
爲了應對該商品的特定文件可以有都相同的「安裝程序」,我們其實應該在「文件」每發射「VAL」作爲第一步聚合「測試」值的情況。使用$max
累加器中的$cond
使此情況成爲「單個」文檔而不是「兩個」,對於每個數組條目都是一個。
當然,另一種情況是簡單地通過應用$setUnion
對初步名單,以避免在這種情況下重複返回值的「設置」:
db.data.aggregate([
{ "$addFields": {
"val": { "$setUnion": [["$installer","$tester"]] }
}},
{ "$unwind": "$val" },
{ "$group": {
"_id": "$val",
"installer": {
"$sum": {
"$cond": [
{ "$eq": ["$installer","$val"] },
1,
0
]
}
},
"tester": {
"$sum": {
"$cond": [
{ "$eq": ["$tester","$val"] },
1,
0
]
}
}
}}
])
我添加了一個文件到您的源作爲:
{ "installer": "jack", "tester": "jack" }
爲了說明結果。
至於$cond
,它是一個「三元」或if..then..else
條件,這裏的參數是「第一」 if
一個條件評價爲布爾型,then
作爲值返回時true
和else
作爲值時返回條件是false
。
可以交替這樣寫:
"$cond": {
"if": { "$eq": ["$installer","$val"] },
"then": 1,
"else": 0
}
但原來的「陣」的語法更簡單一點寫簡單表達式。大多數人仍然會認識到它的「三元」,但如果你認爲它使代碼更清晰,那麼你可以使用「命名鍵」形式。
當然結果是1
當該字段是存在於文檔中僅返回,使正確的計數:
/* 1 */
{
"_id" : "jack",
"installer" : 1.0,
"tester" : 1.0
}
/* 2 */
{
"_id" : "dave",
"installer" : 0.0,
"tester" : 2.0
}
/* 3 */
{
"_id" : "bob",
"installer" : 1.0,
"tester" : 1.0
}
/* 4 */
{
"_id" : "chris",
"installer" : 2.0,
"tester" : 1.0
}
/* 5 */
{
"_id" : "anthony",
"installer" : 2.0,
"tester" : 1.0
}
添加初始「陣列」的文檔可以交替使用$project
來完成如果你的MongoDB版本不支持$addFields
。唯一不同的是「明確的」,包括那些以後需要其他字段:
{ "$project": {
"tester": 1,
"installer": 1,
"val": { "$setUnion": [["$installer","$tester"]] }
}}
如果你的MongoDB是實際上仍然比MongoDB的3.2,它允許這是一個「陣列」的符號,那麼你可以使用$map
代替舊的從MongoDB的2.6和向上:
{ "$project": {
"tester": 1,
"installer": 1,
"val": {
"$setUnion": [
{ "$map": {
"input": ["A","B"],
"as": "a",
"in": {
"$cond": [{ "$eq": ["$$a", "A"] }, "$installer", "$tester"]
}
}
]
}
}}
再次使用$cond
以交替地選擇呈現作爲數組元素,其值。
此外,你真的應該避免做一些事情,比如在語句結尾添加$project
。你當然可以這樣做,但這確實意味着前一個管道階段的所有結果都將「再次運行」,以便進行其他更改。對於將"_id"
更改爲"name"
這樣微不足道的事情,通常只需接受將「分組鍵」稱爲_id
並將其留在那裏的做法通常會更好。
作爲$group
結果,它實際上是「唯一標識符」爲其_id
是通用術語。
這應該對你有幫助:https://stackoverflow.com/questions/18501064/mongodb-aggregation-counting-distinct-fields –