node.js - Mongoose - 查找每个用户的最后一条消息

标签 node.js mongodb mongoose unique

我正在处理消息系统,我需要从每个向登录用户发送消息的用户那里获取最后一条消息。我在 mongoDB 中有这个结构:

[{
    "_id": "551bd621bb5895e4109bc3ce",
    "from": "admin",
    "to": "user1",
    "message": "message1",
    "created": "2015-04-01T11:27:29.671Z"
}, {
    "_id": "551bd9acf26208ac1d9b831d",
    "from": "user1",
    "to": "admin",
    "message": "message2",
    "created": "2015-04-01T11:42:36.936Z"
}, {
    "_id": "551bdd6d849d53001dd8a64a",
    "from": "user1",
    "to": "user2",
    "message": "message3",
    "created": "2015-04-01T11:58:37.858Z"
}, {
    "_id": "551bdd99849d53001dd8a64b",
    "from": "user2",
    "to": "admin",
    "__v": 0,
    "message": "message4",
    "created": "2015-04-01T11:59:21.005Z"
}, {
    "_id": "551bdda1849d53001dd8a64c",
    "from": "user1",
    "to": "admin",
    "__v": 0,
    "message": "message5",
    "created": "2015-04-01T11:59:29.971Z"
}]

我需要从向登录用户发送消息的每个用户的最后一条消息中获取字段 frommessagecreated。我尝试使用 distinct,但它只返回一个字段。我有这个:

Message.find({
        to: req.user.username
    })
    .select('message created')
    .sort('-created')
    .exec(function (err, messages) {
        if (err) {
            return res.status(400).send({
                message: getErrorMessage(err)
            });
        } else {
            res.json(messages)
        }
    });

但它返回所有向登录用户发送消息的用户,我只需要唯一用户和他们的最后一条消息。有没有办法用 Mongoose 做到这一点?

最佳答案

在您的管道阶段具有 $match 的情况下使用聚合框架, $sort , $group$project表达式:

Message.aggregate(
    [
        // Matching pipeline, similar to find
        { 
            "$match": { 
                "to": req.user.username
            }
        },
        // Sorting pipeline
        { 
            "$sort": { 
                "created": -1 
            } 
        },
        // Grouping pipeline
        {
            "$group": {
                "_id": "$from",
                "message": {
                    "$first": "$message" 
                },
                "created": {
                    "$first": "$created" 
                }
            }
        },
        // Project pipeline, similar to select
        {
             "$project": { 
                "_id": 0,
                "from": "$_id",
                "message": 1,
                "created": 1
            }
        }
    ],
    function(err, messages) {
       // Result is an array of documents
       if (err) {
            return res.status(400).send({
                message: getErrorMessage(err)
            });
        } else {
            res.json(messages)
        }
    }
);

如果 req.user.username = "admin",使用您的示例集合,那么结果是:

{
    "result" : [ 
        {
            "message" : "message4",
            "created" : "2015-04-01T11:59:21.005Z",
            "from" : "user2"
        }, 
        {
            "message" : "message5",
            "created" : "2015-04-01T11:59:29.971Z",
            "from" : "user1"
        }
    ],
    "ok" : 1
}

关于node.js - Mongoose - 查找每个用户的最后一条消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29410749/

相关文章:

html - 套接字 IO - 新 session 触发断开连接

javascript - 发布 http ://localhost:3000/404 (Not Found)

ruby-on-rails - MongoDB崩溃了!我的数据去哪儿了?

node.js - Mongoose 日期格式

javascript - Mongoose 预 Hook : pull _id from array on remove

node.js - 使用 AsyncIterator 等待 x of y 会导致内存泄漏

node.js - 将 Uint8Array 转换为 node.js 中等效的十六进制字符串

mongodb - Mongo Aggregation 删除一个 id 的所有记录,只保留最旧的记录

java - 带有 MongoTemplate 的 Spring Boot

arrays - Mongoose - 查找数组没有任何匹配项的文档