你quesstion不是非常清晰,但似乎什麼你想在這裏做的是計數字段中的數據的發生,可選地通過匹配標準的值來過濾這些字段。
這裏$cond
運營商允許您將logical condition等轉換成數值:
db.collection.aggregate([
{ "$group": {
"_id": null,
"name": { "$sum": 1 },
"salary": {
"$sum": {
"$cond": [
{ "$gte": [ "$salary", 1000 ] },
1,
0
]
}
},
"type": {
"$sum": {
"$cond": [
{ "$eq": [ "$type", "type2" ] },
1,
0
]
}
}
}}
])
的所有值均在同一文件中,並沒有真正使任何意義,他們在這裏分手了,因爲這是額外的正在籌備中。
{ "_id" : null, "name" : 3, "salary" : 3, "type" : 2 }
否則在長期的形式,這是不是很高性能由於需要使每個文檔的副本,每一個鍵看起來像這樣:
db.collection.aggregate([
{ "$project": {
"name": 1,
"salary": 1,
"type": 1,
"category": { "$literal": ["name","salary","type"] }
}},
{ "$unwind": "$category" },
{ "$group": {
"_id": "$category",
"count": {
"$sum": {
"$cond": [
{ "$and": [
{ "$eq": [ "$category", "name"] },
{ "$ifNull": [ "$name", false ] }
]},
1,
{ "$cond": [
{ "$and": [
{ "$eq": [ "$category", "salary" ] },
{ "$gte": [ "$salary", 1000 ] }
]},
1,
{ "$cond": [
{ "$and": [
{ "$eq": [ "$category", "type" ] },
{ "$eq": [ "$type", "type2" ] }
]},
1,
0
]}
]}
]
}
}
}}
])
而且它的輸出:
{ "_id" : "type", "count" : 2 }
{ "_id" : "salary", "count" : 3 }
{ "_id" : "name", "count" : 3 }
如果您的文檔沒有統一的密鑰名稱,或者無法在管道條件中指定每個密鑰,請使用mapReduce代替:
db.collection.mapReduce(
function() {
var doc = this;
delete doc._id;
Object.keys(this).forEach(function(key) {
var value = ((key == "salary") && (doc[key] < 1000))
? 0
: ((key == "type") && (doc[key] != "type2"))
? 0
: 1;
emit(key,value);
});
},
function(key,values) {
return Array.sum(values);
},
{
"out": { "inline": 1 }
}
);
而且它的輸出:
"results" : [
{
"_id" : "name",
"value" : 3
},
{
"_id" : "salary",
"value" : 3
},
{
"_id" : "type",
"value" : 2
}
]
這基本上是一個有條件的計數同樣的事情,但你只指定了「反向」的狀況下,你想,只爲要到田間地頭過濾條件。當然,這種輸出格式很容易作爲單獨的文檔發佈。
同樣的方法適用於在條件滿足的條件下測試滿足條件的條件並返回1
滿足條件的條件或0
不適用於總計計數的條件。
你會更好地展示你目前在做什麼。你的解釋目前還不清楚,因爲你的「參數」與你所要的輸出的關係。 –
@布萊克斯,我的標準將是或條件(例如薪水> 10000,姓名= xxx)在這個標準中,我需要得到通過這個標準的工資數和曾經有過相同名字的人數。 –