我刚刚开始使用mongodb并且已经阅读了有关聚合的文档,但仍然在努力将sql语句的等效知识与mongo中使用的方法联系起来。
我有这些数据:
{
"_id" : ObjectId("53ac7bce4eaf6de4d5601c19"),
"uid" : ObjectId("53ac7bb84eaf6de4d5601c15"),
"mid" : ObjectId("53ab27504eaf6de4d5601be4"),
"score" : 1
},{
"_id" : ObjectId("53ac7bce4eaf6de4d5601c1a"),
"uid" : ObjectId("53ac7bb84eaf6de4d5601c16"),
"mid" : ObjectId("53ab27504eaf6de4d5601be4"),
"score" : 5
}
...
我正试图达到这个结果:
{
"uid" : ObjectId("53ac7bb84eaf6de4d5601c15"),
"uid_2" : ObjectId("53ac7bb84eaf6de4d5601c16"),
"mid" : ObjectId("53ab27504eaf6de4d5601be4"),
"score" : 1,
"score_2" : 5,
"difference" : 4
}
...
我将每个uid与一个中间的uid进行比较并计算其得分的差异(不能是负差异,只有正数)。
我遇到的大多数例子都不符合我的要求,希望有些mongo guru可以帮助我。谢谢!
答案 0 :(得分:1)
如上所述,我认为您的数据建模有点偏离,因为您需要一些东西来“匹配”“匹配”。我在这里有一个“简化”案例:
{
"_id" : ObjectId("53ae9da2e24682cac4215e0c"),
"match" : ObjectId("53ae9d78e24682cac4215e0b"),
"score" : 1
}
{
"_id" : ObjectId("53ae9da5e24682cac4215e0d"),
"match" : ObjectId("53ae9d78e24682cac4215e0b"),
"score" : 5
}
{
"_id" : ObjectId("53aea6cde24682cac4215e15"),
"match" : ObjectId("53aea6c1e24682cac4215e14"),
"score" : 2
}
{
"_id" : ObjectId("53aea6e4e24682cac4215e16"),
"match" : ObjectId("53aea6c1e24682cac4215e14"),
"score" : 1
}
{
"_id" : ObjectId("53aea6eae24682cac4215e18"),
"match" : ObjectId("53aea6e6e24682cac4215e17"),
"score" : 2
}
{
"_id" : ObjectId("53aea6ece24682cac4215e19"),
"match" : ObjectId("53aea6e6e24682cac4215e17"),
"score" : 2
}
基本上代表的是“六个”不同比赛中“六支”球队的得分。
鉴于此,我对结果的看法是:
db.matches.aggregate([
// Group on matches and find the "min" and "max" score
{ "$group": {
"_id": "$match",
"teams": {
"$push": {
"_id": "$_id",
"score": "$score"
}
},
"minScore": { "$min": "$score" },
"maxScore": { "$max": "$score" }
}},
// Unwind the "teams" array created
{ "$unwind": "$teams" },
// Compare scores for "win", "loss" or "draw"
{ "$group": {
"_id": "$_id",
"win": {
"$min": { "$cond": [
{ "$and": [
{ "$eq": [ "$teams.score", "$maxScore" ] },
{ "$gt": [ "$teams.score", "$minScore" ] }
]},
"$teams",
false
]}
},
"loss": {
"$min": { "$cond": [
{ "$and": [
{ "$eq": [ "$teams.score", "$minScore" ] },
{ "$lt": [ "$teams.score", "$maxScore" ] }
]},
"$teams",
false
]}
},
"draw": {
"$push": { "$cond": [
{ "$eq": [ "$minScore", "$maxScore" ] },
"$teams",
false
]}
},
"difference": {
"$max": { "$subtract": [ "$maxScore", "$minScore" ] }
}
}},
// Just fix up those "draw" results with a [false,false] array
{ "$project": {
"win": 1,
"loss": 1,
"draw": { "$cond": [
{ "$gt": [
{ "$size": { "$setDifference": [ "$draw", [false] ] } },
0
]},
"$draw",
false
]},
"difference": 1
}}
])
这给你一个非常好的结果:
{
"_id" : ObjectId("53ae9d78e24682cac4215e0b"),
"win" : {
"_id" : ObjectId("53ae9da5e24682cac4215e0d"),
"score" : 5
},
"loss" : {
"_id" : ObjectId("53ae9da2e24682cac4215e0c"),
"score" : 1
},
"draw" : false,
"difference" : 4
}
{
"_id" : ObjectId("53aea6c1e24682cac4215e14"),
"win" : {
"_id" : ObjectId("53aea6cde24682cac4215e15"),
"score" : 2
},
"loss" : {
"_id" : ObjectId("53aea6e4e24682cac4215e16"),
"score" : 1
},
"draw" : false,
"difference" : 1
}
{
"_id" : ObjectId("53aea6e6e24682cac4215e17"),
"win" : false,
"loss" : false,
"draw" : [
{
"_id" : ObjectId("53aea6eae24682cac4215e18"),
"score" : 2
},
{
"_id" : ObjectId("53aea6ece24682cac4215e19"),
"score" : 2
}
],
"difference" : 0
}
这基本上是每次“匹配”的结果,并确定胜利者和宽松者之间的“差异”,同时确定哪支球队“赢了”或“输了”。最后阶段使用了一些仅在MongoDB 2.6中引入的运算符,但如果您没有该版本可用则不需要。或者,如果你想通过$unwind
和其他一些处理,你实际上仍然可以做同样的事情。