MongoDB只展开第一项

时间:2016-11-21 06:03:49

标签: mongodb

我有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_iduser_idmessage_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)               

1 个答案:

答案 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()