我有Mongo 3.2数据库,收集了对话。每个元素都是这样的:
{
"_id" : ObjectId("582e9f85160238a44ef0bfbd"),
"conversation_id" : 39,
"owner_id" : 8,
"title" : "Title",
"recipients" : 1,
"last_modified" : "2016-10-28 06:21:35",
"locked" : 0,
"recipients_details" : [
{
"user_id" : 1,
"last_message" : "2016-10-28 06:21:35"
},
{
"user_id" : 8,
"last_message" : "2016-10-28 06:14:00"
}
]
}
我想让在会话中发布最后一条消息的所有用户都包含一些 user_id 。例如,如果我想获得用户#8的所有对话,请在上面的JSON' recipients_details'应该只包含1条user_id = 1的记录,因为他的消息是最后一条。我已经尝试过这段代码了,但是它提供了所有记录并解除它不是解决方案(在本声明中):
db.conversations.aggregate([
{$match:{'recipients_details.user_id':1}},
{$sort:{'last_modified':-1}},
{$project:{_id:1,last_modified:1,recipients_details:1}}
])
UPD :从2个MySQL表(对话和收件人(conversation_id
,user_id
,message_posted
))迁移了结构。我想找到这个SQL的模拟:
SELECT * FROM `recipients` WHERE `conversation_id` IN (SELECT `conversation_id` FROM `recipients` WHERE `user_id` = 1) AND `user_id` <> 1 GROUP BY `conversation_id` ORDER BY `message_posted` DESC
结果我得到了:
conversation_id user_id message_posted
--------------- ------- ---------------------
40 164 2016-11-01 12:13:23
39 8 2016-10-28 06:14:00
27 65 2016-10-26 14:26:59
23 65 2016-10-26 14:23:59
24 62 2016-10-26 08:44:14
20 62 (NULL)
25 76 (NULL)
42 64 (NULL)
43 65 (NULL)
44 68 (NULL)
答案 0 :(得分:1)
在查看原始数据之后,您似乎首先找到包含recipients_details.user_id:8
的文档,然后在recipients_details
数组中查找last_message
值,并获取第一个值。所以为此我应该使用mongo数组设置操作我使用$setDifference和$filter所以首先我过滤匹配的users_id,然后使用set difference来获得排序数据和数据的最后一个展开结果的差异将所有结果分组。检查以下查询:
db.collectionName.aggregate({
"$match": {
"recipients_details.user_id": {
"$in": [8]
}
}
}, {
"$project": {
"filter": {
"$setDifference": ["$recipients_details", {
"$filter": {
"input": "$recipients_details",
"as": "recp",
"cond": {
"$eq": ["$$recp.user_id", 8]
}
}
}]
},
"conversation_id": 1,
"owner_id": 1,
"title": 1,
"recipients": 1,
"last_modified": 1,
"locked": 1
}
}, {
"$unwind": "$filter"
}, {
"$sort": {
"filter.last_message": -1
}
}, {
"$group": {
"_id": "$_id",
"conversation_id": {
"$first": "$conversation_id"
},
"owner_id": {
"$first": "$owner_id"
},
"title": {
"$first": "$title"
},
"recipients": {
"$first": "$recipients"
},
"last_modified": {
"$first": "$last_modified"
},
"locked": {
"$first": "$locked"
},
"recipients_details": {
"$first": {
"user_id": "$filter.user_id",
"last_message": "$filter.last_message"
}
}
}
}).pretty()