2015-05-21 2 views
0

Я использую Node.js и MongoDB (Mongoose.js) в своем проекте. В нем есть какая-то система обмена сообщениями. Коллекция, которая хранит сообщения имеет следующую схему:Как получить список пользователей в MongoDB, у которых есть хотя бы N-готовые сообщения?

{ 
    message: "Some message text", 
    user: "54835b0c3d36170c0c6da7f5", 
    read: 0 
} 

user - это идентификатор пользователя, с которым это сообщение адресовано. read Поле имеет два возможных значения: 0 - пользователь еще не прочитал сообщение, 1 - уже прочитанное сообщение.

Проблема заключается в получении списка идентификаторов пользователей, у которых есть 5 и более непрочитанных сообщений. Наиболее очевидным решением является получение списка всех непрочитанных сообщений, их повторение и создание списка пользователей на его основе. Но это выглядит не лучшим решением (с точки зрения производительности).

Я думаю, что должен быть лучший способ добиться этого. Возможно, используя структуру агрегации.

Я был бы признателен за любую помощь :)

ответ

3

Вы можете использовать следующую схему агрегирования:

db.collection.aggregate([ 
    { 
     "$match": { "read": 0 } 
    }, 
    { 
     "$group": { 
      "_id": "$user", 
      "unread_count": { "$sum": 1 } 
     }   
    }, 
    { 
     "$match": { 
      "unread_count": { "$gte": 5 } 
     } 
    } 
]) 
+1

легко и просто, мой '$ cond' было слишком много :) – bagrat

+0

В чем разница между использованием агрегации и выполнения запроса с' оператора gte' $ ? – diegoaguilar

+0

@ diegoaguilar Выполнение запроса с помощью оператора '$ gte' потребует поля, в котором будет содержаться количество непрочитанных сообщений, а в текущей схеме этого нет, поэтому для получения счета вам потребуется агрегация. – chridam

0

Точно, используя структуру агрегации :) как это:

db.messages.aggregate([ 
         { 
          $group: { 
             _id: "$user", 
             unread_messages: {$sum: {$cond: ["$read", 0, 1]}} 
            }, 
         }, 
         { 
          $match: { 
             unread_messages: {$gte: 5} 
            } 
         } 
         ]) 

Дело в том, что мы $group все сообщения каждого пользователя, и добавить 1 на непрочитанные сообщения, если поле read - 0.

Тогда вы только $match документы, имеющие новые unread_messages больше или равно 5.

Смежные вопросы

 Смежные вопросы