按数组计数分组 MongoDB
Group By Count on Array MongoDB
这是我数据库中约 1000 万行中的一个:
{
"_id" : ObjectId("58f569159f809c49ffc5cdbb"),
"date" : ISODate("2017-03-21T09:10:07.686Z"),
"p1" : {
"_id" : 1765906,
"deck" : [
33,
25,
59,
38,
62,
3,
33,
57
],
"crowns" : 3
},
"p2" : {
"_id" : 2520156,
"deck" : [
25,
69,
86,
8,
44,
61,
69,
50
],
"crowns" : 2
}
}
游戏对战记录。牌组是由 8 张不同的牌组成的阵列。我正在尝试找到获胜次数最多的卡片。可以通过比较王冠来确定获胜者(我设法 select 玩家 1 获胜的所有文件)。
我想要实现的目标:
不幸的是,我无法执行 return 我正在寻找的组查询(获胜次数最多的卡片)。
我也在尝试找到最成功的牌组(获胜次数足够 - 应忽略该数组中指定的牌的顺序)。
我已经尝试过,但 return一段时间后出现空错误:
db.battle_logs.aggregate([
{
$addFields: {
"player1won": { "$cmp": [ "$p1.crowns", "$p2.crowns" ] }
}
},
{ $match: { "player1won": 1 }},
{
$group:
{
_id: "$p1.deck",
count: { $sum: 1 }
}
}
], {
allowDiskUse:true,
cursor:{}
})
我希望将所有套牌组合按获胜次数分组(只考虑玩家 1 的获胜次数)
由于您在组查询中使用数组p1.deck
作为_id
,您需要对数组进行排序,否则卡片的顺序将创建一个新组。
以下内容可能适合您的情况:
1)
db.battle_logs.aggregate([
{
$addFields: {
"player1won": { "$cmp": [ "$p1.crowns", "$p2.crowns" ] }
}
},
//Fiter out ties
{
$match: {
"$or" : [
{"player1won": 1}, //Player 1 won
{"player1won" : -1} //Player 2 won
]
}
},
// Get the winning deck
{
$project: {
"deck": { $cond : [ { $gte : [ "$p1.crowns", "$p2.crowns" ]}, "$p1.deck", "$p2.deck" ]}
}
},
//Unwind the deck to get every card
{
$unwind : "$deck"
},
//Get count of each card
{
$group : {
"_id" : "$deck" ,
"count" : {"$sum" : 1}
}
},
// Sort on count
{
$sort: {"count" : -1}
},
//Get the card with highest count
{
$limit: 1
}
], {
allowDiskUse:true,
cursor:{}
})
2)
db.battle_logs.aggregate([
{
$addFields: {
"player1won": { "$cmp": [ "$p1.crowns", "$p2.crowns" ] }
}
},
//Fiter out ties
{
$match: {
"$or" : [
{"player1won": 1}, //Player 1 won
{"player1won" : -1} //Player 2 won
]
}
},
// Get the winning deck
{
$project: {
"deck": { $cond : [ { $gte : [ "$p1.crowns", "$p2.crowns" ]}, "$p1.deck", "$p2.deck" ]}
}
},
//Unwind the deck to get every card
{
$unwind : "$deck"
},
//Sort the cards
{
$sort : {"deck": 1}
},
//Group sorted cards back in deck
{
$group : {
"_id" : "$_id" ,
"deck" : {"$push" : "$deck"}
}
},
{
$group:
{
_id: "$deck",
count: { $sum: 1 }
}
}
], {
allowDiskUse:true,
cursor:{}
})
这是我数据库中约 1000 万行中的一个:
{
"_id" : ObjectId("58f569159f809c49ffc5cdbb"),
"date" : ISODate("2017-03-21T09:10:07.686Z"),
"p1" : {
"_id" : 1765906,
"deck" : [
33,
25,
59,
38,
62,
3,
33,
57
],
"crowns" : 3
},
"p2" : {
"_id" : 2520156,
"deck" : [
25,
69,
86,
8,
44,
61,
69,
50
],
"crowns" : 2
}
}
游戏对战记录。牌组是由 8 张不同的牌组成的阵列。我正在尝试找到获胜次数最多的卡片。可以通过比较王冠来确定获胜者(我设法 select 玩家 1 获胜的所有文件)。
我想要实现的目标:
不幸的是,我无法执行 return 我正在寻找的组查询(获胜次数最多的卡片)。
我也在尝试找到最成功的牌组(获胜次数足够 - 应忽略该数组中指定的牌的顺序)。
我已经尝试过,但 return一段时间后出现空错误:
db.battle_logs.aggregate([
{
$addFields: {
"player1won": { "$cmp": [ "$p1.crowns", "$p2.crowns" ] }
}
},
{ $match: { "player1won": 1 }},
{
$group:
{
_id: "$p1.deck",
count: { $sum: 1 }
}
}
], {
allowDiskUse:true,
cursor:{}
})
我希望将所有套牌组合按获胜次数分组(只考虑玩家 1 的获胜次数)
由于您在组查询中使用数组p1.deck
作为_id
,您需要对数组进行排序,否则卡片的顺序将创建一个新组。
以下内容可能适合您的情况:
1)
db.battle_logs.aggregate([
{
$addFields: {
"player1won": { "$cmp": [ "$p1.crowns", "$p2.crowns" ] }
}
},
//Fiter out ties
{
$match: {
"$or" : [
{"player1won": 1}, //Player 1 won
{"player1won" : -1} //Player 2 won
]
}
},
// Get the winning deck
{
$project: {
"deck": { $cond : [ { $gte : [ "$p1.crowns", "$p2.crowns" ]}, "$p1.deck", "$p2.deck" ]}
}
},
//Unwind the deck to get every card
{
$unwind : "$deck"
},
//Get count of each card
{
$group : {
"_id" : "$deck" ,
"count" : {"$sum" : 1}
}
},
// Sort on count
{
$sort: {"count" : -1}
},
//Get the card with highest count
{
$limit: 1
}
], {
allowDiskUse:true,
cursor:{}
})
2)
db.battle_logs.aggregate([
{
$addFields: {
"player1won": { "$cmp": [ "$p1.crowns", "$p2.crowns" ] }
}
},
//Fiter out ties
{
$match: {
"$or" : [
{"player1won": 1}, //Player 1 won
{"player1won" : -1} //Player 2 won
]
}
},
// Get the winning deck
{
$project: {
"deck": { $cond : [ { $gte : [ "$p1.crowns", "$p2.crowns" ]}, "$p1.deck", "$p2.deck" ]}
}
},
//Unwind the deck to get every card
{
$unwind : "$deck"
},
//Sort the cards
{
$sort : {"deck": 1}
},
//Group sorted cards back in deck
{
$group : {
"_id" : "$_id" ,
"deck" : {"$push" : "$deck"}
}
},
{
$group:
{
_id: "$deck",
count: { $sum: 1 }
}
}
], {
allowDiskUse:true,
cursor:{}
})