Структура коллекции разговоров 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 как последний компонент), это означает, что вы можете использовать его как для самого запроса, так и для сортировки сообщений, что означает повышение производительности.

Другие вопросы по тегам