如果你有MongoDB的3.2可用,那麼你可以做這樣的事情:
db.sample.aggregate([
{ "$project": {
"apdata": {
"$arrayElemAt": [
{ "$filter": {
"input": "$apdata",
"as": "el",
"cond": {
"$eq": [
"$$el.level",
{ "$max": {
"$map": {
"input": "$apdata",
"as": "data",
"in": "$$data.level"
}
}}
]
}
}},
0
]
}
}},
{ "$group": {
"_id": "$apdata.bssid",
"ssid": { "$first": "$apdata.ssid" },
"count": { "$sum": 1 }
}}
])
至少對於MongoDB的2.6你需要這樣做:
db.sample.aggregate([
{ "$unwind": "$apdata" },
{ "$group": {
"_id": "$_id",
"apdata": { "$push": "$apdata" },
"max": { "$max": "$apdata.level" }
}},
{ "$unwind": "$apdata" },
{ "$redact": {
"$cond": {
"if": { "$eq": [ "$apdata.level", "$max" ] },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
{ "$group": {
"_id": "$apdata.bssid",
"ssid": { "$first": "$apdata.ssid" },
"count": { "$sum": 1 }
}}
])
而且MongoDB的2.4或2.2這樣:
db.sample.aggregate([
{ "$unwind": "$apdata" },
{ "$group": {
"_id": "$_id",
"apdata": { "$push": "$apdata" },
"max": { "$max": "$apdata.level" }
}},
{ "$unwind": "$apdata" },
{ "$project": {
"apdata": 1,
"isMax": { "$eq": [ "$apdata.level", "$max" ] }
}},
{ "$match": { "isMax": true } },
{ "$group": {
"_id": "$apdata.bssid",
"ssid": { "$first": "$apdata.ssid" },
"count": { "$sum": 1 }
}}
])
在所有情況下$max
用於在第一個文檔中獲取每個文檔中數組的「最大」值,然後您可以使用它在「$group
」中使用之前「過濾」數組內容。這種方法僅針對版本
MongoDB 3.2:允許$max
直接在值的「數組」上工作。因此,$map
用於獲取"level"
值,並找出「最大值」實際上是多少。
然後可用於返回與「max」值相匹配的數組元素,最後使用$arrayElemAt
作爲普通返回該「唯一」元素(在兩個可能的和「零」索引中)文件。
整個過程可以在$group
做「唯一」,如果你基本上重複整個語句既_id
,爲了得到$first
"ssid"
價值,但它更容易在$project
寫分別展示了一下。
MongoDB 2.6:這缺乏發燒友操作員,最值得注意的是$max
「直接」在陣列上工作的能力。值得注意的是需要$unwind
陣列第一個,然後實際上$group
只是在原始文件,只爲了得到「最大」的價值。
然後該過程確實需要您再次$unwind
,因爲您將在稍後對數組中的元素進行分組,然後使用$redact
來過濾內容。這是$match
的「邏輯」形式,您可以直接將"level"
與早期階段計算的「最大值」進行比較。因此,不是「最大」的元素被刪除。
MongoDB 2。4:又是基本相同的邏輯,除了代替$redact
,你實際上需要物理$project
才能在文檔中放置一個字段用於使用$match
進行過濾。
所有版本都有相同的最終$group
,在那裏你提供的路徑,"apdata.bssid"
的分組鍵和$first
結果爲"ssid"
和簡單$sum
該分組邊界上計算分組鍵的出現在結果。
一切只返回如下:
{ "_id" : "f4:b7:e2:56:e4:20", "ssid" : "Test Network2", "count" : 1 }
{ "_id" : "b8:a3:86:67:03:56", "ssid" : "Test Network1", "count" : 2 }
其實最 「有效」 的形式MongoDB的3.2將如下所示:
db.sample.aggregate([
{ "$group": {
"_id": {
"$arrayElemAt": [
{ "$map": {
"input": {
"$filter": {
"input": "$apdata",
"as": "el",
"cond": {
"$eq": [
"$$el.level",
{ "$max": {
"$map": {
"input": "$apdata",
"as": "data",
"in": "$$data.level"
}
}}
]
}
}
},
"as": "apdata",
"in": {
"bssid": "$$apdata.bssid",
"ssid": "$$apdata.ssid"
}
}},
0
]
},
"count": { "$sum": 1 }
}}
])
有了一個稍微不同的形式,由於化合物_id
,但它只是一個單獨的$group
階段,沒有重複整個過程來查找「最大」值的數組元素數據:
{
"_id" : {
"bssid" : "b8:a3:86:67:03:56",
"ssid" : "Test Network1"
},
"count" : 2
}
{
"_id" : {
"bssid" : "f4:b7:e2:56:e4:20",
"ssid" : "Test Network2"
},
"count" : 1
}
_id通常是一個唯一的標識符。你怎麼能通過它分組? –
@JohnGreenall如果您遵循問題中的邏輯,它會要求對每個數組中僅有「兩個」的「appdata.bssid」值進行分組。問題的關鍵在於*「將特定網絡的層次數與所有文檔的最大值相比」*作爲與問題和數據相關的最佳短語。還有一個問題有一些值得注意的解決方法。 –