Структура коллекции разговоров Mongodb (как узнать количество новых сообщений)
Я разрабатываю диалоговое окно для сайта, где структура документов выглядит следующим образом:
{
'_id' : {'$id' :'507f1f77bcf86cd799439011'}
'user_a' : {
'user_id' : {'$id' :'54304264e77cc5a1670cb318'},
'updated' : '2014-11-01 19:56:09.000Z'
},
'user_b' : {
'user_id' : {'$id' :'53efcb8fe77cc56550a049d0'},
'updated' : '2014-11-01 19:56:09.000Z'
},
'updated' : '2014-11-01 19:56:09.000Z',
'messages' : [
{
'user_id' : {'$id' :'54304264e77cc5a1670cb318'},
'text' : "some text goes here..."
},
{
'user_id' : {'$id' :'53efcb8fe77cc56550a049d0'},
'text' : "some text goes here..."
},
}
Я ищу способ узнать количество новых сообщений, полученных пользователем с момента последней проверки. когда пользователь проверяет сообщение, я устанавливаю "обновленное" время пользователя на время, когда он проверял сообщение, и когда пользователь отправляет новое сообщение, я обновляю "обновленное" свойство документа.
Я играл с различными агрегатными комбинациями, чтобы найти пользователя, у которого дата обновления пользователя старше даты обновления документа, есть ли способ сделать это или есть лучший способ спроектировать структуру документы для этого?
Обновить
Я изменил дизайн на основе ответа Макса Ноэля - добавив дату / отметку времени к каждому сообщению, чтобы новая структура выглядела следующим образом:
{
'_id' : {'$id' :'507f1f77bcf86cd799439011'}
'user_a' : {'$id' :'54304264e77cc5a1670cb318'},
'user_b' : {'$id' :'53efcb8fe77cc56550a049d0'},
'updated' : '2014-11-01 19:56:09.000Z',
'messages' : [
{
'user_id' : {'$id' :'54304264e77cc5a1670cb318'},
'text' : "some text goes here...",
'added' : '2014-11-01 19:56:09.000Z',
'read' : false,
},
{
'user_id' : {'$id' :'53efcb8fe77cc56550a049d0'},
'text' : "some text goes here...",
'added' : '2014-11-01 19:56:09.000Z',
'read' : '2014-11-01 22:56:09.000Z',
},
}
используя следующую статистическую функцию, я получил счетчик всех сообщений с идентификатором user_id, не похожим на тот, который я просматриваю, и прочитал статус false.
$found = $db->collection->aggregate(
array(
array( '$match' => array( '$or' => array(
array('user_a' => $user_id),
array('user_b' => $user_id)
)
)
),
array( '$project' => array( 'M' => '$messages', '_id' => 0) ),
array( '$unwind' => '$M'),
array( '$match' => array(
'M.user_id' => array( '$ne' => $user_id ),
'M.read' => false
)
),
array( '$group' => array(
'_id' => 1,
'count' => array( '$sum' => 1 )
)
)
)
);
1 ответ
Если время, когда пользователь последний раз проверял свою входящую почту, является вашим триггером, это означает, что сообщения должны иметь date
атрибут (дата-время, правда, но тоже самое). Таким образом, вы можете запросить все сообщения с date
больше, чем время последнего обновления, и если вы что-то получите, это означает, что есть сообщения, которые пользователь не видел.
Кроме того, если вы создаете индекс на messages.date
(реально это будет составной индекс с messages.date
как последний компонент), это означает, что вы можете использовать его как для самого запроса, так и для сортировки сообщений, что означает повышение производительности.