Node.js Mongoose-查询集合,对数组字段进行排序,然后根据已排序的数组字段对查询文档进行排序

时间:2018-07-19 20:28:50

标签: arrays node.js sorting mongoose aggregation

说我的数据库中有这些文件

{ 
    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});
            });
        })
    });

这导致对消息进行排序,但对对话进行排序。有什么想法可以解决这个问题吗?

0 个答案:

没有答案