Mongodb 组 _id 中的聚合无序项目

Mongodb Aggregation orderless items in Group _id

我将用户之间的消息存储在具有此架构的集合中:

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

我正在尝试查询数据库以生成当前用户对话的列表,就像使用此聚合嵌入最后一条消息的 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"),
        }
    ]
}

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

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

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