MongoDB聚合按ObjectId数组匹配



收集

我有一个收集了以下数据的深渊蝙蝠:

[
{
"floor_level": "12-2",
"battle_index": 1,
"party": [
"60b6edd41ec85acb419565dc",
"60b6edd41ec85acb419565e3",
"60b6edd41ec85acb41956648",
"60b6edd41ec85acb41956669"
]
},
{
"floor_level": "12-3",
"battle_index": 1,
"party": [
"60b6edd41ec85acb419565dc",
"60b6edd41ec85acb419565e3",
"60b6edd41ec85acb41956648",
"60b6edd41ec85acb41956669"
]
},
{
"floor_level": "12-1",
"battle_index": 1,
"party": [
"60b6edd41ec85acb419565dc",
"60b6edd41ec85acb419565e3",
"60b6edd41ec85acb41956648",
"60b6edd41ec85acb41956669"
]
},
{
"floor_level": "12-1",
"battle_index": 2,
"party": [
"60b6ee621ec85acb4195b0c6",
"60b6ee621ec85acb4195b0d2",
"60b6ee621ec85acb4195b0e8",
"60ba56671ec85acb41045ff5"
]
},
{
"floor_level": "12-2",
"battle_index": 2,
"party": [
"60b6ee621ec85acb4195b0c6",
"60b6ee621ec85acb4195b0d2",
"60b6ee621ec85acb4195b0e8",
"60ba56671ec85acb41045ff5"
]
}
]

我主要通过floor_levelparty阵列中的ObjectIds进行过滤。我尝试聚合party包含完全相同的4个ObjectId(已排序(的记录。我想根据它们所属的floor_levelbattle_index对它们进行分组,并求和party的计数。

期望结果

我试图实现的结果看起来是这样的:

[
{ 
floor: "12-1-1",
parties: [
{ 
party: [
"60b6ee621ec85acb4195b0c6",
"60b6ee621ec85acb4195b0d2",
"60b6ee621ec85acb4195b0e8",
"60ba56671ec85acb41045ff5"
],
count: 23
},
{ 
party: [
"60b6edd41ec85acb419565dc",
"60b6edd41ec85acb419565e3",
"60b6edd41ec85acb41956648",
"60b6edd41ec85acb41956669"
],
count: 13
},
...
].
},
{ 
floor: "12-1-2",
parties: [
{ 
party: [
"60b6ee621ec85acb4195b0c6",
"60b6ee621ec85acb4195b0d2",
"60b6ee621ec85acb4195b0e8",
"60ba56671ec85acb41045ff5"
],
count: 52
},
{ 
party: [
"60b6edd41ec85acb419565dc",
"60b6edd41ec85acb419565e3",
"60b6edd41ec85acb41956648",
"60b6edd41ec85acb41956669"
],
count: 13
},
...
]
}
]

其中,count表示为各个floor找到的特定party的数目。每个floor将在阵列中具有多个party,每个party是4个ObjectIds的唯一组合。

示例

假设我们在这里有一个简化版本的集合:

[
{
"floor_level": "12-1",
"battle_index": 1,
"party": [ 1, 2, 3, 4 ]
},
{
"floor_level": "12-1",
"battle_index": 1,
"party": [ 1, 2, 4, 5 ]
},
{
"floor_level": "12-1",
"battle_index": 1,
"party": [ 1, 2, 4, 5]
},
{
"floor_level": "12-2",
"battle_index": 1,
"party": [ 1, 2, 3, 4]
},
{
"floor_level": "12-2",
"battle_index": 1,
"party": [ 1, 2, 4, 5]
}
]

如果我查询floor_levels["12-1","12-2"],我希望看到这个输出:

[
{
"floor": "12-1",
"parties": [
{ 
"party": [ 1, 2, 3, 4 ],
"count": 1
},
{ 
"party": [ 1, 2, 4, 5 ],
"count": 2
}
]
},
{
"floor": "12-2",
"parties": [
{ 
"party": [ 1, 2, 3, 4 ],
"count": 1
},
{ 
"party": [ 1, 2, 4, 5 ],
"count": 1
}
]
}
]

尝试

我试着引用这里的资源:通过多个字段的mongodb组值

db.aggregate([
{ "$group": {
"floor": { $concat: [$floor_level, $battle_index] },
}},
{ "$lookup": {
"from": "party",
"pipeline": [
{ "$match": { 
"$expr": { "$eq": [ "$party", "$$party"] }
}},
{ "$group": {
"party": "$party",
"count": { "$sum": 1 }
}},
{ "$sort": { "count": -1  } },
],
"as": "parties"
}}
])

但我发现,使用稍微复杂一点的嵌套数组和对象结构更难实现我的结果。

形成更新的预期输出,希望这能帮助您

db.collection.aggregate([
{
"$group": {
"_id": { level: "$floor_level", party: "$party" },
"count": { "$sum": 1 }
}
},
{
"$group": {
"_id": "$_id.level",
"parties": {
"$push": {
party: "$_id.party",
count: "$count"
}
}
}
}
])

正在工作的Mongo游乐场

假设你也需要对击球指数进行分组,你可以使用

db.collection.aggregate([
{
"$group": {
"_id": { level: "$floor_level", party: "$party", index:"$battle_index" },
"count": { "$sum": 1 }
}
},
{
"$group": {
"_id": { "level": "$_id.level", "index": "$_id.index" },    
"parties": {
"$push": {
party: "$_id.party",
count: "$count"
}
}
}
},
{
$addFields: {
floor: { "$concat": [ "$_id.level", "-", { $toString: "$_id.index" } ] },
_id: "$$REMOVE",
index: "$$REMOVE"
}
}
])

正在工作的Mongo游乐场

最新更新