我在Mongo中有以下文档架构:
{
"_id": "an id",
"title": "my title",
"muted": "true",
"participants": [{ "userid":12345, "more": "data" }, ... ],
"messages": [{ "message", "details " } ... { } ]
}
我正试图以这种形式获得一系列对象:
[
{
"_id": "an id",
"meta"
{
"title": "my title",
"muted": "true",
"participants": [12345, /* user ids only */ ],
},
"messages": [{ "message", "details " } ... { } ]
}
]
我有聚合工作来生成消息和_id:
[
{ $match:
{
'participants.user_id': userId
}
},
{ $unwind: "$messages" },
{ $match: { 'messages.sent_at': { '$gte': new Date(date) }}},
{ $group: { _id: "$_id", messages: { $addToSet: "$messages" }}}
]
获取元数据需要什么魔力?
答案 0 :(得分:2)
如果您想在输出“参与者”中匹配'participants.userid': 12345
db.collection.aggregate(
[
{ $match:
{
'participants.userid': 12345
}
},
{ $unwind : "$participants"},
{ $match:
{
'participants.userid': 12345
}
},
{ $unwind: "$messages" },
{ $group: { _id: "$_id" , muted : { $first : '$muted'}, title : { $first : '$title'}, messages: { $addToSet: "$messages" }, participants: { $addToSet: "$participants.userid" }}},
{ $project : { "messages" : "$messages" ,'meta.muted': '$muted', 'meta.title': '$title', 'meta.participants': '$participants'} },
]
).result
如果您想要participants
中的所有用户ID,无论它是什么。
db.collection.aggregate(
[
{ $match:
{
'participants.userid': 12345
}
},
{ $project : { "messages" : 1 ,"muted" : 1 , "title" : 1 , "messages" : 1 , "participants" : 1, "ids" : "$participants.userid" } },
{ $unwind : "$participants"},
{ $match:
{
'participants.userid': 12345
}
},
{ $unwind: "$messages" },
{ $group: { _id: "$_id" ,
muted : { $first : '$muted'}, title : { $first : '$title'},
ids : { $first : '$ids'},
messages: { $addToSet: "$messages" },
participants: { $addToSet: "$participants.userid" }}},
{ $project : { "messages" : "$messages" ,'meta.muted': '$muted', 'meta.title': '$title', 'meta.participants': '$ids'} },
]
).result
输出:
{
"0" : {
"_id" : "an id",
"messages" : [
{
"message2" : "details2 "
},
{
"message" : "details "
}
],
"meta" : {
"muted" : "true",
"title" : "my title",
"participants" : [
12345
]
}
}
}
答案 1 :(得分:0)
在上一篇$group
语句中,您需要告诉Mongo应该返回哪些字段。目前,您要求的所有内容都是_id
和messages
字段。假设您的聚合返回三个文档:
{
"_id": 1111,
"title": "my title",
"muted": "true",
"participants": [{ "userid":12345, "more": "data" }, ... ],
"messages": { "message": "Foo" }
},
{
"_id": 1111,
"title": "my title",
"muted": "true",
"participants": [{ "userid":12345, "more": "data" }, ... ],
"messages": { "message": "Bar" }
},
{
"_id": 1111,
"title": "my title",
"muted": "true",
"participants": [{ "userid":12345, "more": "data" }, ... ],
"messages": { "message": "Baz" }
}
您已经向Mongo询问了$push
运营商所有消息的列表,因此我们已经覆盖了这些消息。对于其他字段,不能执行此操作:
{$group: {
_id: "$_id",
title: 1,
muted: "$muted"
}}
毕竟,Mongo如何知道如何处理三个"my title"
值?或者muted
的三个布尔值?做一个数组?丢弃数据?连接它们?
在这种情况下,由于所有三个值总是相同(按照定义),你可以说“我不在乎,只给我任何一个”,“给我第二个结果”,“给我第一个“或”给我最后一个“。前两个是不可能的,因此我们选择了$first
或$last
:
{$group: {
_id: "$_id",
title: {$first: "$title"},
muted: {$first: "$muted"}
}}
当然,在这种情况下使用哪一个并不重要。