Akh*_*eni 3 mongodb nosql aggregation-framework
我试图在用户之间的聊天中获取最后一条消息。以下是我的文档中的收藏。
{
"toUser":123,"fromUser":456,"message":"1 from suresh","timeStamp":"2019-10-09 16:39:14:1414 PM +05:30",
"toUser":456,"fromUser":123,"message":"Man super man ","timeStamp":"2019-10-09 16:43:09:0909 PM +05:30",
"toUser":456,"fromUser":123,"message":"Kk","timeStamp":"2019-10-09 18:31:12:1212 PM +05:30"
"toUser":456,"fromUser":123,"message":"It working man","timeStamp":"2019-10-09 18:31:18:1818 PM +05:30"
"toUser":456,"fromUser":123,"message":"2","timeStamp":"2019-10-09 18:31:21:2121 PM +05:30"
"toUser":101,"fromUser":123,"message":"Kk","timeStamp":"2019-10-09 18:31:12:1212 PM +05:30"
}
Run Code Online (Sandbox Code Playgroud)
我使用 mongo 查询作为
db.chats.aggregate(
[
{$match:{$or:[{"toUser":123},{"fromUser":123}]}},
{ "$sort": { "timeStamp": -1}},
{
"$group": {
"_id": {fromUser:"$fromUser",toUser:"$toUser"},
"fromUser": {"$first":"$fromUser"},
"toUser" : {"$first":"$toUser"},
"message": {"$first": "$message" },
"timeStamp": { "$first": "$timeStamp"}
}
},
]
);
Run Code Online (Sandbox Code Playgroud)
我的输出是
{ "_id" : { "fromUser" : 456, "toUser" : 123 }, "fromUser" : 456, "toUser" : 123, "message" : "1 from suresh", "timeStamp" : "2019-10-09 16:39:14:1414 PM +05:30" }
{ "_id" : { "fromUser" : 123, "toUser" : 101 }, "fromUser" : 123, "toUser" : 101, "message" : "Kk", "timeStamp" : "2019-10-09 18:31:12:1212 PM +05:30" }
{ "_id" : { "fromUser" : 123, "toUser" : 456 }, "fromUser" : 123, "toUser" : 456, "message" : "2", "timeStamp" : "2019-10-09 18:31:21:2121 PM +05:30" }
Run Code Online (Sandbox Code Playgroud)
但是如果你看看 123 到 456 个用户之间的实际最后一条消息是message:2
所以我需要如下按时间戳排序的最终输出。
{ "_id" : { "fromUser" : 123, "toUser" : 456 }, "fromUser" : 123, "toUser" : 456, "message" : "2", "timeStamp" : "2019-10-09 18:31:21:2121 PM +05:30" }
{ "_id" : { "fromUser" : 123, "toUser" : 101 }, "fromUser" : 123, "toUser" : 101, "message" : "Kk", "timeStamp" : "2019-10-09 18:31:12:1212 PM +05:30" }
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮我解决查询。
提前致谢。
问题在于消息是怎样的stored。
存储的数据:
fromUser 123 and toUser 456
fromUser 456 and toUser 123
Run Code Online (Sandbox Code Playgroud)
所以,当你把它分组时,逻辑上它们是相同的,但是not for grouping。
解决方案:
我们需要确保发送者/接收者始终以相同的方式到达
1. Create array where we store sender / receiver
2. Order that array `[123, 456] [456, 123] => [123,456], [123,456]`
3. Group by this ordered array (In Mongo way: $project, $unwind, $sort, $group - push)
Run Code Online (Sandbox Code Playgroud)
db.chats.aggregate([
{
$match: {
$or: [
{
"toUser": 123
},
{
"fromUser": 123
}
]
}
},
{
"$project": {
toUser: 1,
fromUser: 1,
message: 1,
timeStamp: 1,
fromToUser: [
"$fromUser",
"$toUser"
]
}
},
{
$unwind: "$fromToUser"
},
{
$sort: {
"fromToUser": 1
}
},
{
$group: {
_id: "$_id",
"fromToUser": {
$push: "$fromToUser"
},
"fromUser": {
"$first": "$fromUser"
},
"toUser": {
"$first": "$toUser"
},
"message": {
"$first": "$message"
},
"timeStamp": {
"$first": "$timeStamp"
}
}
},
{
"$sort": {
"timeStamp": -1
}
},
{
"$group": {
"_id": "$fromToUser",
"fromUser": {
"$first": "$fromUser"
},
"toUser": {
"$first": "$toUser"
},
"message": {
"$first": "$message"
},
"timeStamp": {
"$first": "$timeStamp"
}
}
}
])
Run Code Online (Sandbox Code Playgroud)
结果
[
{
"_id": [
101,
123
],
"fromUser": 123,
"message": "Kk",
"timeStamp": "2019-10-09 18:31:12:1212 PM +05:30",
"toUser": 101
},
{
"_id": [
123,
456
],
"fromUser": 123,
"message": "2",
"timeStamp": "2019-10-09 18:31:21:2121 PM +05:30",
"toUser": 456
}
]
Run Code Online (Sandbox Code Playgroud)