在MongoDB中列出涉及用户的每个对话的最后一条消息

让我们说我有一个看起来像这样的消息的mongo数据库:

{ "_id": ObjectId("5458009c1ab2354c029d7178"), "to": "dan", "from": "wood", "message": "hi dan how are you?", "time": new Date(1415053468590), "__v": 0 } { "_id": ObjectId("545800b45eaf364d026c1cba"), "to": "wood", "from": "dan", "message": "hi wood how are you?", "time": new Date(1415053492125), "__v": 0 } { "_id": ObjectId("5458009c1ab2354c029d7178"), "to": "billy", "from": "wood", "message": "hi billy how are you?", "time": new Date(1415053468590), "__v": 0 } { "_id": ObjectId("545800b45eaf364d026c1cba"), "to": "wood", "from": "billy", "message": "hi wood how are you?", "time": new Date(1415053492125), "__v": 0 } 

那么如何从用户“木头”可能有的每个对话中检索最后一条消息呢?

其他人已经发布了一个类似的问题,如何在MySQL中做到这一点。 我在问如何用mongoose做这个。

我会张贴它作为参考incase它有助于: 私人消息系统。 列出每个对话的最后一条消息

如果你能帮助我,那将会很棒。 感谢您的帮助。 对此,我真的非常感激。 我对mongoose,mongodb和node.js是新的。 我来自一个PHP的MySQL背景。

如果你可以发布实际的代码,这将是很好的,所以我可以尝试一下并提供反馈。 谢谢。

我的数据库模式如下所示:

 var messageSchema = new Schema({ to: { type: String, required: true}, from: { type: String, required: true}, message: { type: String, required: true}, time : { type : Date, default: Date.now } }); 

certificate什么样的人运行这个网站: http : //i62.tinypic.com/bbntx.jpg

离开这个网站,你可以知道什么样的不友好的人正在运行这个网站。 我可能会问别的地方。 他们实际上并不关心帮助你。 他们关心他们的规则。 你一个新的人,他们不欢迎你。 身份证是欢迎其他任何地方不被像对待像这样的污垢对待。

欢迎来到堆栈溢出。 这是一个体面的问题,你张贴。 请让我尽我所能来帮助你。

这是一个可以在mongo shell中运行的聚合命令。 请在线find解释。

 db.collection.aggregate([ //match all those records which involve Wood. {$match:{$or:[{"to":"wood"},{"from":"wood"}]}}, // sort all the messages by descending order {$sort:{time:-1}}, { // Now we need to group messages together, based on the to and from field. // We generate a key - "last_message_between", with the value being a concatenation // result of the values in to and from field. // Now, Messages from Wood to billy and Billy to wood should be treated under a single group right. // To achieve that, we do a small trick to make the result contain the name coming last // alphabetically, first. So our key for all the Messages from Wood to Billy and Billy to Wood would be // "Wood and Billy". // And then we just display the first document that appears in the group, that would be the // latest Message. $group:{"_id":{ "last_message_between":{ $cond:[ { $gt:[ {$substr:["$to",0,1]}, {$substr:["$from",0,1]}] }, {$concat:["$to"," and ","$from"]}, {$concat:["$from"," and ","$to"]} ] } },"message":{$first:"$$ROOT"} } } ]) 

你可以在mongoose上运行下面的代码。

 Collection.aggregate( {$match:{$or:[{"to":"wood"},{"from":"wood"}]}}, {$sort:{time:-1}}, { $group:{"_id":{ "last_message_between":{ $cond:[ { $gt:[ {$substr:["$to",0,1]}, {$substr:["$from",0,1]}] }, {$concat:["$to"," and ","$from"]}, {$concat:["$from"," and ","$to"]} ] } },"message":{$first:"$$ROOT"} } }, function(err, res) { if (err) return handleError(err); console.log(res); } )