Мангуст счетчик вставлять элементы массива с агрегатом - PullRequest
0 голосов
/ 16 ноября 2018

В настоящее время я пытаюсь достичь чего-то, что было бы тривиально в SQL, но действительно болезненно с Mongoose / MongoDb 3.3.

У меня есть коллекция разговоров. Разговор начинается эмитентом и состоит из нуля или более сообщений. сообщения обмениваются между эмитентом и пользователем и хранятся в массиве сообщений. Моя задача довольно проста, посчитайте количество непрочитанных сообщений для данного эмитента.

Один разговор для одного эмитента может выглядеть следующим образом:

{
    "_id" : ObjectId("578caba0264f76ec80d87e7c"),
    "issuer" : ObjectId("578c9c68261246f717343ab7"),
    "messages" : [
        {
            "content" : "Hi !",
            "type" : "text",
            "user" : ObjectId("56582b17b380912011c485e2"),
            "_id" : ObjectId("578caba08cf9a9081927e326"),
            "createdAt" : ISODate("2016-07-18T10:12:48.778Z"),
            "seenAt" : ISODate("2016-07-18T10:13:16.725Z")
        },
        {
            "content" : "Wassup ?",
            "type" : "text",
            "user" : ObjectId("569a9d343bd9840e26797412"),
            "_id" : ObjectId("578cabcb8cf9a9081927e327"),
            "createdAt" : ISODate("2016-07-18T10:13:31.254Z"),
            "seenAt" : ISODate("2016-07-18T10:13:34.133Z")
        },
        {
            "content" : "Fine, ya ?",
            "type" : "text",
            "user" : ObjectId("569a9d343bd9840e26797412"),
            "_id" : ObjectId("578cabd38cf9a9081927e328"),
            "createdAt" : ISODate("2016-07-18T10:13:39.573Z")
        }
    }
}

Я до сих пор пробовал использовать агрегацию Mongoose:

function findUnreadByIssuerId(issuerId) {
    return Conversation
    .aggregate()
    .match({ issuer: issuerId })
    .unwind('messages')
    .match({'messages.seenAt' : { $exists: 'false'} })
    .count()
    .exec();
}

Дело в том, что nodejs жалуется на то, что count () не является функцией. Похоже, что с агрегатами все в порядке, так как, если я уберу count (), я получу массив.

Затем я попытался использовать $ group, но я новичок в Mongo и его группировке и получаю пустой массив:

return Conversation .aggregate([
    { $match: { issuer: issuerId } },
    { $unwind: '$messages' },
    { $match: {'messages.seenAt' : { $exists: 'false'} } },
    { $group: {
        _id: '$messages.createdAt',
        count: { $sum: 1 }
    }}
    ])
    .exec();

В приведенном примере ожидаемый результат вызова будет в идеале 2. Но я могу справиться с {sum: 2}, хотя и не идеально. Что не так с моей цепочкой агрегатов Mongoose?

1 Ответ

0 голосов
/ 16 ноября 2018

Для Монго> = 3,4:

Вы должны предоставить аргумент для $ count, который является именем столбца счета.

https://docs.mongodb.com/manual/reference/operator/aggregation/count/

Используйте это как:

.count("total_unseen")

не целое число, а объект {total_unseen: 1}

Для Монго <3,4 </p>

Используйте $ group и количество:

{ $group: null, count: {$sum: 1} }

Относительно результата: Если один из этапов в конвейере пуст, результат будет пустым, но обычно драйвер приводит к более правильному значению.

Так что для обоих методов, когда счетчик равен 0, результатом будет пустой массив или ноль. (зависит от водителя)

...