说我的数据库中有这些文件
{
id: 2,
participants: [
6, 23 // these reference 'User' and need to be populated
],
messages: [
{ time: 20, val: 'b' },
{ time: 12, val: 'a' },
{ time: 30, val: 'c' }
]
},
{
id: 1,
participants: [
6, 49 // these reference 'User' and need to be populated
],
messages: [
{ time: 50, val: 'be' },
{ time: 1, val: 'ab' },
{ time: 20, val: 'cs' }
]
},
{
id: 3,
participants: [
23, 49 // these reference 'User' and need to be populated
],
messages: [
{ time: 4, val: 'jkl' },
{ time: 25, val: 'uty' },
{ time: 34, val: 'zsw' }
]
}
我想查询用户在参与者数组中的所有文档,按日期对消息数组进行排序,并通过查看最新消息对文档进行排序。最后,我想填充参与者数组。
因此,如果用户ID为6,则结果应如下所示。
{
id: 1,
participants: [
{id: 6, ...}, {id: 49, ...}
],
messages: [
{ time: 1, val: 'ab' },
{ time: 20, val: 'cs' },
{ time: 50, val: 'be' }
]
},
{
id: 2,
participants: [
{id: 6, ...}, {id: 23, ...}
],
messages: [
{ time: 12, val: 'a' },
{ time: 20, val: 'b' },
{ time: 30, val: 'c' }
]
}
是否有一种方法可以在1个汇总中完成所有这些操作?一个问题是我不能在聚合中使用$ elemMatch,因此我什至无法查询聚合中的相关文档。我必须做两个单独的查询。这就是我到目前为止所拥有的。
Conversation.find({
participants:{$elemMatch:{user: req.user._id}}
})
.exec(function(err, conversations){
if(err) {
return res.status(500).json(err.toString());
}
Conversation.aggregate([
{
$match: { "_id": { $in: _.map(conversations, function(convo) {return convo._id; }) } }
},
{
$unwind: '$messages'
},
{
$sort: { 'messages.date': 1 } // sorts actual messages
},
{
$group: {
_id: {_id: "$_id", participants: "$participants"}, messages: {$push: "$messages"}
}
},
{
$project: {
_id: "$_id._id",
participants: "$_id.participants",
messages: "$messages"
}
},
{
$sort: { 'messages.date': 1 } // expected to sort conversations but has no effect
}
])
.exec(function(err, convos) {
if(err) {
return res.status(500).json(err.toString());
}
User.populate(convos, {path: 'participants.user'}, function(err, populatedConvos) {
conn.close();
if(err) {
return res.status(500).json(err.toString());
}
return res.status(200).json({conversations: populatedConvos});
});
})
});
这导致对消息进行排序,但对对话进行排序。有什么想法可以解决这个问题吗?