我收集了一系列以這種方式塑造的足球比賽:
{
_id: ObjectId("SomeUniqueMatchID"),
players: [
{ team: "Arsenal", name: "Saka", distanceRan: 8590},
{ team: "Arsenal", name: "Aubameyang", distanceRan: 9230}
// ...remaining players for both teams
],
timestamp: 129380193,
// other match info
}
我想查詢奧巴梅揚和薩卡一起比賽時跑的平均距離,不管他們在哪支球隊,只要他們在同一個隊踢球。
我了解$unwind球員領域,然后$match最后$group用來計算平均值,但是當我在運行查詢之前不了解團隊時,我不知道在 $match 條件上寫什么。
uj5u.com熱心網友回復:
查詢1
- 放松球員
- 匹配只保留 2 個玩家的名字
- 分組
match_idteam并推動陣列中的距離 - 匹配并只保留大小為 2 的陣列(這是關鍵,大小=2 僅當這些球員在同一場比賽和同一團隊中都參加過比賽時)
(如果您在示例代碼中看到 id=2,id=3 是被忽略,因為這些球員從未參加過同一場比賽和同一支球隊) - uwnind 距離(這里我們知道所有這些都是有效的)
- group by
null(所有集合1組)并平均距離(你不關心什么比賽,什么球隊或哪個球員,所以只保留關于avgDistance的資訊)
測驗代碼在這里
aggregate(
[{"$unwind": {"path": "$players"}},
{"$match":
{"$expr":
{"$or":
[{"$eq": ["$players.name", "Saka"]},
{"$eq": ["$players.name", "Aubameyang"]}]}}},
{"$group":
{"_id": {"_id": "$_id", "team": "$players.team"},
"distances": {"$push": "$players.distanceRan"}}},
{"$match": {"$expr": {"$eq": [{"$size": "$distances"}, 2]}}},
{"$unwind": {"path": "$distances"}},
{"$group": {"_id": null, "avgDistanceRan": {"$avg": "$distances"}}},
{"$unset": ["_id"]}])
查詢2
- 本地它使用reduce,以及1場比賽中的1名球員,最多1次和最多1支球隊的事實(即使這不是真的,query1也能作業)
- 減少以保持這兩個距離,只有當團隊相同并且名稱是兩者之一時,我們才添加距離陣列
- 再次保持距離計數=2(以確保同一支球隊的同一場比賽中的兩名球員)
- 展開并按空分組,平均如上
測驗代碼在這里
aggregate(
[{"$set":
{"players":
{"$reduce":
{"input": "$players",
"initialValue": {"team": null, "distances": []},
"in":
{"$cond":
[{"$and":
[{"$or":
[{"$eq": ["$$this.name", "Saka"]},
{"$eq": ["$$this.name", "Aubameyang"]}]},
{"$or":
[{"$eq": ["$$value.team", null]},
{"$eq": ["$$value.team", "$$this.team"]}]}]},
{"team": "$$this.team",
"distances":
{"$concatArrays":
["$$value.distances", ["$$this.distanceRan"]]}},
"$$value"]}}}}},
{"$match": {"$expr": {"$eq": [{"$size": "$players.distances"}, 2]}}},
{"$unwind": {"path": "$players.distances"}},
{"$group":
{"_id": null, "avgdistanceRan": {"$avg": "$players.distances"}}},
{"$unset": ["_id"]}])
uj5u.com熱心網友回復:
我相信我明白你在找什么,但如果這是錯誤的,請告訴我。
正如您所說,您應該能夠為此使用聚合管道,包括 $match、$avg 和 $group。
您可以在此處查看查詢的實時演示。
資料庫
如果我們有以下資料庫結構...
[
{
_id: ObjectId("123456789101819202122232"),
players: [
{
team: "Arsenal",
name: "Saka",
distanceRan: 8590
},
{
team: "Arsenal",
name: "Aubameyang",
distanceRan: 9230
}
],
timestamp: 129380193,
},
{
_id: ObjectId("123456789101819202999999"),
players: [
{
team: "Arsenal",
name: "Saka",
distanceRan: 7777
},
{
team: "NotArsenal",
name: "Aubameyang",
distanceRan: 9999
}
],
timestamp: 129399999,
}
]
詢問
我們可以使用以下查詢來計算平均值。
db.collection.aggregate([
{
$unwind: "$players"
},
{
$match: {
$or: [
{
"players.name": "Saka",
"players.team": "Arsenal"
},
{
"players.name": "Aubameyang",
"players.team": "Arsenal"
}
]
}
},
{
$group: {
_id: "$_id",
averageDistanceRan: {
$avg: "$players.distanceRan"
},
"players": {
$push: "$players"
}
}
},
{
"$match": {
"$expr": {
"$eq": [
{
"$size": "$players"
},
2
]
}
}
},
{
$project: {
_id: "$_id",
averageDistanceRan: 1
}
}
])
結果
這會給我們...
[
{
"_id": ObjectId("123456789101819202122232"),
"averageDistanceRan": 8910
}
]
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/371136.html
