Агрегирование Mongodb беспорядочных элементов в группе _id - PullRequest
0 голосов
/ 26 июня 2018

Я храню сообщения между пользователями в коллекции с этой схемой:

{
        "_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"),
        }
    ]
}

Как мне справиться с агрегацией? Какие-либо предложения? Спасибо.

1 Ответ

0 голосов
/ 26 июня 2018

Конечно, вы можете справиться с агрегацией! Поскольку ваши _id s равны ObjectId s, вы можете сравнить их с реляционными операторами, поэтому вы можете использовать $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'}}
    }
])
...