_id组中的Mongodb聚合无序项目

时间:2018-06-26 11:11:16

标签: mongodb aggregation

我使用以下模式在集合中的用户之间存储消息:

{
        "_id" : ObjectId("5b23c455e3fce278f9e8d05f"), //message id
        "f" : ObjectId("5ad13aaa1ba073601cc16bca"), //sender userid
        "c" : "Hi", //contents
        "t" : ObjectId("5ad2de5c691a4008cf6923b4"), //reciever userid
}

我正在尝试查询db来生成当前用户对话的列表,就像使用此聚合嵌入了最后一条消息的whatsapp列表一样:

    db.getCollection('message').aggregate(
   [
     { $match: { $or: [ { f: ObjectId("5ad13aaa1ba073601cc16bca") }, {t:ObjectId("5ad13aaa1ba073601cc16bca")} ] } },
      {
        $group : {
           _id :{f:"$f",t:"$t"},
          c: { $push: "$$ROOT" } 
        }
      }
   ]
)

结果是:

{
    "_id" : {
        "f" : ObjectId("5ad13aaa1ba073601cc16bca"),
        "t" : ObjectId("5ad2de5c691a4008cf6923b4")
    },
    "c" : [ 
        {
            "_id" : ObjectId("5b23c455e3fce278f9e8d05f"),
            "f" : ObjectId("5ad13aaa1ba073601cc16bca"),
            "c" : "Hi",
            "t" : ObjectId("5ad2de5c691a4008cf6923b4"),
            "d" : ISODate("2018-06-15T13:48:34.000Z"),
        }
    ]
},
{
    "_id" : {
        "f" : ObjectId("5ad2de5c691a4008cf6923b4"),
        "t" : ObjectId("5ad13aaa1ba073601cc16bca")
    },
    "c" : [ 
        {
            "_id" : ObjectId("5b235fea43966a767d2d9604"),
            "f" : ObjectId("5ad2de5c691a4008cf6923b4"),
            "c" : "Hello",
            "t" : ObjectId("5ad13aaa1ba073601cc16bca"),
            "d" : ISODate("2018-06-15T06:40:07.000Z"),
        }
    ]
}

如您所见,在5ad13aaa1ba073601cc16bca和5ad2de5c691a4008cf6923b4之间存在对话。该组按其顺序作用于f和t。但是,我们确实需要查找对话,而不管f和t的顺序如何。因此,结果文档应该像这样,其中嵌入了最新消息:

{
    "_id" : {
        "x" : ObjectId("5ad13aaa1ba073601cc16bca"),
        "y" : ObjectId("5ad2de5c691a4008cf6923b4")
    },
    "c" : [ 
        {
            "_id" : ObjectId("5b23c455e3fce278f9e8d05f"),
            "f" : ObjectId("5ad13aaa1ba073601cc16bca"),
            "c" : "Hi",
            "t" : ObjectId("5ad2de5c691a4008cf6923b4"),
            "d" : ISODate("2018-06-15T13:48:34.000Z"),
        }
    ]
}

如何通过聚合处理此问题?有什么建议么?谢谢。

1 个答案:

答案 0 :(得分:1)

当然,您可以通过聚合来处理它!由于您的_idObjectId,因此可以将它们与关系运算符进行比较,因此可以在它们上使用$max$min

db.getCollection('message').aggregate([
    {$match: {$or: [{f: _id}, {t: _id}]}},
    {$group: {
        _id: {
            x: {$max: ['$f', '$t']},
            y: {$min: ['$f', '$t']}
        },
        c: {$push: '$$ROOT'}}
    }
])