我对如何实现这一点感到有些困惑,希望有人能帮助我解决这个问题!
我的文件看起来像这样:
{
"_id" : NumberLong("1213477"),
"players" : [
{
"acc_id" : 1,
"cards" : [
{
"id" : 112,
"l" : 3
},
{
"id" : 121,
"l" : 6
},
{
"id" : 123
},
{
"id" : 126
},
{
"id" : 130,
"l" : 8
},
{
"id" : 139,
"l" : 6
},
{
"id" : 103,
"l" : 6
},
{
"id" : 111
}
]
},
{
"acc_id" : 52,
"cards" : [
{
"id" : 112,
"l" : 2
},
{
"id" : 121,
"l" : 5
},
{
"id" : 123
},
{
"id" : 132
},
{
"id" : 139,
"l" : 5
},
{
"id" : 104,
"l" : 2
},
{
"id" : 108,
"l" : 8
},
{
"id" : 108,
"l" : 1
}
]
}
]
}
所以,这个游戏中有两个玩家,每个玩家都有8张牌。我想运行一些查询,并找出有多少人使用相同的确切卡。最后,我应该能够列出最受欢迎的套牌。 (每张卡都有特定用途)
非常感谢任何帮助......谢谢!
答案 0 :(得分:2)
如果我理解不当,mongodb aggregation framework以及$unwind,$group和$match管道和$sum运算符应该适合你。
因此,基于以下集合(非常类似于您上面发布的):
db.game_players.insert({
"players" : [
{
"acc_id" : 1,
"cards" : [
{"id" : 112, "l" : 3 },
{"id" : 121, "l" : 6 },
{"id" : 123 },
{"id" : 126 },
{"id" : 130, "l" : 8},
{"id" : 139, "l" : 6 },
{"id" : 103, "l" : 6 },
{"id" : 111 }
]
},
{
"acc_id" : 52,
"cards" : [
{"id" : 112, "l" : 2 },
{"id" : 121, "l" : 5 },
{"id" : 123 },
{"id" : 132 },
{"id" : 139, "l" : 5 },
{"id" : 104, "l" : 2 },
{"id" : 108, "l" : 8 },
{"id" : 108, "l" : 1 }
]
}
]
})
db.game_players.aggregate([{$unwind: '$players'}])
它从输入文档解构数组字段,以输出每个元素的文档。输出是这样的:
{
"_id" : ObjectId("580d792676d77d5928600787"),
"players" : {
"acc_id" : 1,
"cards" : [
{
"id" : 112,
"l" : 3
},
{
"id" : 121,
"l" : 6
},
{
"id" : 123
},
{
"id" : 126
},
{
"id" : 130,
"l" : 8
},
{
"id" : 139,
"l" : 6
},
{
"id" : 103,
"l" : 6
},
{
"id" : 111
}
]
}
}
{
"_id" : ObjectId("580d792676d77d5928600787"),
"players" : {
"acc_id" : 52,
"cards" : [
{
"id" : 112,
"l" : 2
},
{
"id" : 121,
"l" : 5
},
{
"id" : 123
},
{
"id" : 132
},
{
"id" : 139,
"l" : 5
},
{
"id" : 104,
"l" : 2
},
{
"id" : 108,
"l" : 8
},
{
"id" : 108,
"l" : 1
}
]
}
}
正如您所看到的,现在每个播放器都是文档而不是数组元素。
在下一阶段,我们将用卡片添加组管道分组:
db.game_players.aggregate([{
$unwind: '$players'
}, {
'$group': {
_id: {
'card': '$players.cards.id'
}
}
}]) {
"_id": {
"card": [112, 121, 123, 132, 139, 104, 108, 108]
}
} {
"_id": {
"card": [112, 121, 123, 126, 130, 139, 103, 111]
}
}
哪个输出:
{ "_id" : { "card" : [ 112, 121, 123, 132, 139, 104, 108, 108 ] } }
{ "_id" : { "card" : [ 112, 121, 123, 126, 130, 139, 103, 111 ] } }
请注意,cards
键已添加到分组中。那是因为我们需要在下一阶段引用它。
db.game_players.aggregate([{
$unwind: '$players'
}, {
'$group': {
_id: {
'card': '$players.cards.id'
}
}
}, {
'$unwind': '$_id.card'
}, {
'$group': {
_id: '$_id.card',
'cards_count': {
'$sum': 1
}
}
}])
目前我们有每张卡的总数。见下面的输出:
{ "_id" : 111, "cards_count" : 1 }
{ "_id" : 103, "cards_count" : 1 }
{ "_id" : 126, "cards_count" : 1 }
{ "_id" : 123, "cards_count" : 2 }
{ "_id" : 108, "cards_count" : 2 }
{ "_id" : 112, "cards_count" : 2 }
{ "_id" : 104, "cards_count" : 1 }
{ "_id" : 139, "cards_count" : 2 }
{ "_id" : 132, "cards_count" : 1 }
{ "_id" : 130, "cards_count" : 1 }
{ "_id" : 121, "cards_count" : 2 }
现在你快到了!
db.game_players.aggregate([{
$unwind: '$players'
}, {
'$group': {
_id: {
'card': '$players.cards.id'
}
}
}, {
'$unwind': '$_id.card'
}, {
'$group': {
_id: '$_id.card',
'cards_count': {
'$sum': 1
}
}
}, {
'$match': {
cards_count: {
'$gte': 2
}
}
}])
最终输出是:
{ "_id" : 123, "cards_count" : 2 }
{ "_id" : 108, "cards_count" : 2 }
{ "_id" : 112, "cards_count" : 2 }
{ "_id" : 139, "cards_count" : 2 }
{ "_id" : 121, "cards_count" : 2 }