我正在做一个简单的程序,通过n个玩家来计算特殊单位的总数。
我有类似的文档(简化),其中数组rosterUnits的长度可以是0到7。总共有7个特殊单位。我需要知道每个单位的球员有多少在名册上。
{
{
_id: ObjectId(...),
member: {
rosterUnits: [ "Unit1", "Unit2", "Unit3", "Unit4"]
}
},
{
_id: ObjectId(...),
member: {
rosterUnits: [ "Unit1", "Unit3"]
}
},
...
}
预期结果如下所示:
{
_id: ...
result: [
{
name: "Unit1"
count: 2
},
{
name: "Unit2"
count: 1
},
{
name: "Unit3"
count: 2
},
...
{
name: "Unit7"
count: 0
}
]
}
如何使用聚合管道实现这一点?
编辑(2023年2月7日)
对不起,各位,我以为我在这里提供了足够的细节,但是...文件非常大,直到这个阶段的管道是非常长的。我想节省你的麻烦与文件
我有一个公会,最多有50名玩家。我搜索公会,然后$解开公会成员,$查找成员以获得成员。
这是我提出的完整查询:
db.getCollection('guilds').aggregate([
{ $match: { 'profile.id': 'jrl9Q-_CRDGdMyNjTQH1rQ' } },
//{ $match: { 'profile.id': { $in : ['jrl9Q-_CRDGdMyNjTQH1rQ', 'Tv_j9nhRTgufvH7C7oUYAA']} } },
{ $project: { member: 1, profile: 1 } },
{ $unwind: "$member" },
{
$lookup: {
from: "players",
localField: "member.playerId",
foreignField: "playerId",
pipeline: [
{
$project: {
profileStat: 1,
rosterUnit: {
$let: {
vars: { gls: ["JABBATHEHUTT:SEVEN_STAR", "JEDIMASTERKENOBI:SEVEN_STAR", "GRANDMASTERLUKE:SEVEN_STAR", "LORDVADER:SEVEN_STAR", "GLREY:SEVEN_STAR", "SITHPALPATINE:SEVEN_STAR", "SUPREMELEADERKYLOREN:SEVEN_STAR"], },
in: {
$reduce: {
input: "$rosterUnit",
initialValue: [],
in: {
$cond: {
if: { $gt: [{ $indexOfArray: ["$$gls", "$$this.definitionId"] }, -1] },
then: { $concatArrays: ["$$value", [{ definitionId: "$$this.definitionId", count: 1 }]] },
else: { $concatArrays: ["$$value", []] }
}
},
}
}
}
}
}
}
],
as: "member"
}
},
{
$addFields: {
member: { $arrayElemAt: ["$member", 0] },
gpStats: {
$let: {
vars: { member: { $arrayElemAt: ["$member", 0] } },
in: {
$reduce: {
input: "$$member.profileStat",
initialValue: {},
in: {
characterGp: {
$arrayElemAt: [
"$$member.profileStat.value",
{
$indexOfArray: [
"$$member.profileStat.nameKey",
"STAT_CHARACTER_GALACTIC_POWER_ACQUIRED_NAME"
]
}
]
},
shipGp: {
$arrayElemAt: [
"$$member.profileStat.value",
{
$indexOfArray: [
"$$member.profileStat.nameKey",
"STAT_SHIP_GALACTIC_POWER_ACQUIRED_NAME"
]
}
]
}
}
}
}
}
}
}
},
{
$group: {
_id: "$profile.id",
guildName: { $first: "$profile.name" },
memberCount: { $first: "$profile.memberCount" },
guildGp: { $first: "$profile.guildGalacticPower" },
totalGp: { $sum: { $sum: [{ $toInt: "$gpStats.characterGp" }, { $toInt: "$gpStats.shipGp" }] } },
avgTotalGp: { $avg: { $sum: [{ $toInt: "$gpStats.characterGp" }, { $toInt: "$gpStats.shipGp" }] } },
characterGp: { $sum: { $toInt: "$gpStats.characterGp" } },
shipGp: { $sum: { $toInt: "$gpStats.shipGp" } },
}
}
])
我想添加新的字段到组中,得到上面想要的结果。如果我在member.rosterUnit上做了$unwind,我该如何返回到成员分组?
(再次打扰,这是我的第一个问题)
3条答案
按热度按时间s8vozzvw1#
$unwind
将rosterUnits
数组分解为单独的文档。$group
按rosterUnits
值对文档进行分组,并计算每个单元的计数。$project
化输出,使其仅包含name和count字段。bpzcxfmw2#
是的,我认为最好的方法是使用聚合。
我相信有更好的方法来解决这个问题,但这里有一个解决方案,我希望它对你的朋友有效。
基本上,我们将使用“$group”聚合,并在其中使用运算符“$cond”和“$in”,我们将逐个验证是否找到了搜索的元素。如果找到了,我们将添加1,如果没有找到,则添加0。
合计:
wgmfuz8q3#
质询
Playmongo