我的消息模型是
owner: Object Id, ref User
recipient: Object Id, ref User
message: String
read: boolean, default false,
created: datetime
我需要在每个对话中获取最后的消息。我找到了一些有用的代码:
Message.aggregate(
{$match:{$or:[{"owner":req.user._id},{"recipient":req.user._id}]}},
{$sort:{created:-1}},
{
$group:{"_id":{
"last_message_between":{
$cond:[
{
$gt:[
{$substr:["$recipient",0,1]},
{$substr:["$owner",0,1]}]
},
{$concat:["$recipient"," and ","$owner"]},
{$concat:["$owner"," and ","$recipient"]}
]
}
},"message":{$first:"$$ROOT"}
}
},
function(err, res)
{
if (err) return handleError(err);
console.log(res);
res.end();
}
)
但问题是我的refs是objectIds而不是字符串,所以上面的代码不起作用。我尝试使用toString转换refs但没有运气。如何将我的对象引用转换为字符串,以便我可以实现上述逻辑?或者有更好的方法吗?
答案 0 :(得分:0)
目前,您无法在聚合管道内将ObjectId转换为String。尽管如此,仍然可以使用聚合管道解决您的问题(并且不需要更改您的数据模式),但解决方案非常难看,而且肯定缺乏性能......
db.msg.aggregate([
{$match: {
$or: [
{"owner": ObjectId("bbbbbbbbbbbbbbbbbbbbbbbb")},
{"recipient": ObjectId("bbbbbbbbbbbbbbbbbbbbbbbb")}
]
}},
// the next section objective is to create a unique conversation identifier
{$group:{
_id :"$_id",
message: {"$last": "$message"},
created: {"$last": "$created"},
ownerArr: {"$push": "$owner"},
recipientArr: {"$push": "$recipient"},
}},
{$project:{
_id: 1,
message: 1,
created: 1,
conversationId: {"$setUnion": ["$ownerArr", "$recipientArr"]}
}},
{$unwind: "$conversationId"},
{$sort: {"conversationId": 1}},
{$group:{
_id: "$_id",
conversationId: {"$push": "$conversationId"},
message: {"$last": "$message"},
created: {"$last": "$created"}
}},
// end of conversationId section
// the solution is now trivial
{$sort: {"created": 1}},
{$group:{
_id: "$conversationId",
lastMessageId: {"$last": "$_id"},
lastMessage: {"$last": "$message"},
lastCreated: {"$last": "$created"}
}}
])
> db.msg.find().toArray()
[
{
"_id" : ObjectId("56c4944645f0a14b5b3f5b9d"),
"owner" : ObjectId("bbbbbbbbbbbbbbbbbbbbbbbb"),
"recipient" : ObjectId("aaaaaaaaaaaaaaaaaaaaaaaa"),
"message" : "qwerty",
"created" : ISODate("2015-01-01T00:00:00Z")
},
{
"_id" : ObjectId("56c4944a45f0a14b5b3f5b9e"),
"owner" : ObjectId("aaaaaaaaaaaaaaaaaaaaaaaa"),
"recipient" : ObjectId("bbbbbbbbbbbbbbbbbbbbbbbb"),
"message" : "qwerty",
"created" : ISODate("2016-01-01T00:00:00Z")
},
{
"_id" : ObjectId("56c4944d45f0a14b5b3f5b9f"),
"owner" : ObjectId("aaaaaaaaaaaaaaaaaaaaaaaa"),
"recipient" : ObjectId("cccccccccccccccccccccccc"),
"message" : "qwerty",
"created" : ISODate("2016-01-01T00:00:00Z")
},
{
"_id" : ObjectId("56c4945145f0a14b5b3f5ba0"),
"owner" : ObjectId("bbbbbbbbbbbbbbbbbbbbbbbb"),
"recipient" : ObjectId("aaaaaaaaaaaaaaaaaaaaaaaa"),
"message" : "qwerty",
"created" : ISODate("2014-01-01T00:00:00Z")
},
{
"_id" : ObjectId("56c4945f45f0a14b5b3f5ba1"),
"owner" : ObjectId("bbbbbbbbbbbbbbbbbbbbbbbb"),
"recipient" : ObjectId("cccccccccccccccccccccccc"),
"message" : "qwerty",
"created" : ISODate("2014-01-01T00:00:00Z")
}
]
{ "_id" : [ ObjectId("aaaaaaaaaaaaaaaaaaaaaaaa"), ObjectId("bbbbbbbbbbbbbbbbbbbbbbbb") ], "lastMessageId" : ObjectId("56c4944a45f0a14b5b3f5b9e"), "lastMessage" : "qwerty", "lastCreated" : ISODate("2016-01-01T00:00:00Z") }
{ "_id" : [ ObjectId("bbbbbbbbbbbbbbbbbbbbbbbb"), ObjectId("cccccccccccccccccccccccc") ], "lastMessageId" : ObjectId("56c4945f45f0a14b5b3f5ba1"), "lastMessage" : "qwerty", "lastCreated" : ISODate("2014-01-01T00:00:00Z") }