在 MongoDB 中,我想对嵌套在另一个文档中的文档数组进行分组,而不影响父文档。
数据库:
db={
"users": [
{
"firstName": "David",
"lastName": "Mueller",
"messages": [
{
"text": "hello",
"type": "PERSONAL"
},
{
"text": "test",
"type": "DIRECT"
}
]
},
{
"firstName": "Mia",
"lastName": "Davidson",
"messages": [
{
"text": "hello world",
"type": "DIRECT"
},
{
"text": ":-)",
"type": "PERSONAL"
},
{
"text": "hi there",
"type": "DIRECT"
}
]
}
]
}
想要的结果:
[
{
"firstName": "David",
"lastName": "Mueller",
"messages": [
{
"_id": "PERSONAL",
"count": 1
},
{
"_id": "DIRECT",
"count": 1
}
]
},
{
"firstName": "Mia",
"lastName": "Davidson",
"messages": [
{
"_id": "PERSONAL",
"count": 1
},
{
"_id": "DIRECT",
"count": 2
}
]
}
]
如果我有一个 ids 数组,我已经知道如何使用 $lookup 的内部管道来做到这一点,但我的问题是如何使用一组嵌入文档来做到这一点。
这是使用查找对具有 ids 的数组进行工作分组的示例。这不是解决方案,因为问题是关于嵌入式文档数组而不是 id 数组。提供此示例只是为了表明当 ids 而不是嵌入文档存储在数组中时,我可以归档所需的结果。
用于查找分组的数据库:
db={
"users": [
{
"firstName": "David",
"lastName": "Mueller",
"messages": [
1,
2
]
},
{
"firstName": "Mia",
"lastName": "Davidson",
"messages": [
3,
4,
5
]
}
],
"messages": [
{
"_id": 1,
"text": "hello",
"type": "PERSONAL"
},
{
"_id": 2,
"text": "test",
"type": "DIRECT"
},
{
"_id": 3,
"text": "hello world",
"type": "DIRECT"
},
{
"_id": 4,
"text": ":-)",
"type": "PERSONAL"
},
{
"_id": 5,
"text": "hi there",
"type": "DIRECT"
}
]
}
通过查找进行分组聚合:
db.users.aggregate([
{
"$lookup": {
"from": "messages",
"localField": "messages",
"foreignField": "_id",
"as": "messages",
"pipeline": [
{
"$group": {
"_id": "$type",
"count": {
"$sum": 1
}
}
}
]
}
}
])
查找分组的结果(这是期望的结果):
[
{
"_id": ObjectId("5a934e000102030405000005"),
"firstName": "David",
"lastName": "Mueller",
"messages": [
{
"_id": "PERSONAL",
"count": 1
},
{
"_id": "DIRECT",
"count": 1
}
]
},
{
"_id": ObjectId("5a934e000102030405000006"),
"firstName": "Mia",
"lastName": "Davidson",
"messages": [
{
"_id": "PERSONAL",
"count": 1
},
{
"_id": "DIRECT",
"count": 2
}
]
}
]
现在回到问题:我想归档相同的结果,但使用顶部提供的嵌入式文档数组。
我不知道如何做到这一点(我尝试了人工智能,很多谷歌搜索和其他论坛都没有成功,你是我放弃之前的最后一个资源),我知道我可以使用 $addField 和 $fitler 过滤嵌入数组,但不能我如何才能仅对嵌入数组进行分组。
请注意,这只是一个简单的例子,我的真实数据结构看起来不同,也可能使用其他分组函数,如 min、sum 等。但我只是想知道在使用查找时归档相同内容的一般方法。
我感谢任何帮助,谢谢你 🙂
messages
_id
(大概是用户 ID)和消息 type
进行分组;并使用 $count
设置 countType。_id
重新分组并使用第一个 doc
(因为对于非消息字段是相同的)
{type: ..., count: countType}
推入消息数组中。_id
doc.messages
设置为上一步推送的数组messages
。doc
替换根,它具有所有正确的信息_id
排序。)db.users.aggregate([
{ $unwind: "$messages" },
{
$group: {
_id: {
_id: "$_id",
type: "$messages.type"
},
countType: { $count: {} },
doc: { $first: "$$ROOT" }
}
},
{
$group: {
_id: "$_id._id",
doc: { $first: "$doc" },
messages: {
$push: {
type: "$_id.type",
count: "$countType"
}
}
}
},
{ $set: { "doc.messages": "$messages" } },
{ $replaceWith: "$doc" }
])