MongoDB中如何计算重复数组元素
我对如何实现这一点有点困惑,希望有人能帮我解决这个问题 我的文档如下所示:MongoDB中如何计算重复数组元素,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我对如何实现这一点有点困惑,希望有人能帮我解决这个问题 我的文档如下所示: { "_id" : NumberLong("1213477"), "players" : [ { "acc_id" : 1, "cards" : [ { "id" : 112, "l" : 3 },
{
"_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
}
]
}
]
}
{
"_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
}
]
}
}
所以,在这个游戏中有两个玩家,每个玩家有8张选择的牌。我想进行一些查询,找出有多少人使用相同的卡片。最后,我应该能够有一个最受欢迎的甲板名单。(每张卡都有特定用途)
任何帮助都将不胜感激。。。谢谢大家! 如果我把它拆得很好,随行器、管道和操作员应该可以为您工作。
因此,基于以下收集(非常像您在上面发布的): 步骤1:释放玩家: 它从输入文档中解构一个数组字段,为每个元素输出一个文档。输出如下所示:
{
"_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
}
]
}
]
}
{
"_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
}
]
}
}
正如您现在看到的,每个播放器都是一个文档,而不是一个数组元素
步骤2:按卡片分组
在下一阶段中,我们将添加分组管道,按卡片分组:
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 ] } }
请注意,卡
键已添加到分组中。那是因为我们需要在下一阶段参考它
第三步:再次放松和分组,并对常用(重复?)卡进行汇总
现在我们有每张牌的总数。请参见下面的输出波纹管:
{ "_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 }
现在你就快到了
步骤4:选择计数大于或等于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 }
如果我把它拆得很好,随行的、管道和操作员应该可以为您工作。
因此,基于以下收集(非常像您在上面发布的): 步骤1:释放玩家: 它从输入文档中解构一个数组字段,为每个元素输出一个文档。输出如下所示:
{
"_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
}
]
}
]
}
{
"_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
}
]
}
}
正如您现在看到的,每个播放器都是一个文档,而不是一个数组元素
步骤2:按卡片分组
在下一阶段中,我们将添加分组管道,按卡片分组:
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 ] } }
请注意,卡
键已添加到分组中。那是因为我们需要在下一阶段参考它
第三步:再次放松和分组,并对常用(重复?)卡进行汇总
现在我们有每张牌的总数。请参见下面的输出波纹管:
{ "_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 }
现在你就快到了
步骤4:选择计数大于或等于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 }
非常好,感谢您详细解释退绕过程。我想要的实际上是上面的第2步,你比我需要的更进一步:)只是加了一个总数,现在我可以计算出哪种组合比较流行。非常感谢你,你是最棒的!非常好,感谢您详细解释退绕过程。我想要的实际上是上面的第2步,你比我需要的更进一步:)只是加了一个总数,现在我可以计算出哪种组合比较流行。非常感谢你,你是最棒的!