2015-04-07 5 views
1

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

{ 
    id: "", 
    inResponseToMessageId: "" 
    to: [] 
    cc: [] 
    bcc: [] 
    subject: "" 
    body: "" 
    owners: [{id:4, status:"read", folder:"inbox"}, {id:1, status:'unread', folder:'inbox'}] 
    dateSent: 
} 

клиент хотел бы, чтобы иметь возможность отображать сообщения как вид на разговоре и одноплодного зрения.

У меня возникли проблемы, выясняя эффективный запрос, который может результаты

  1. Возврата сгруппированные по ветке сообщений.
  2. Хорошо работать с разбиением на страницы.
  3. Сортировка по дате и теме.

Я могу изменить структуру данных, но мне нужно, чтобы это хорошо работало.

Ниже приведены несколько возможных решений, но все они, кажется, не дотягивают: сообщения

  • магазин как дети объекта потока.
  • Добавить threadId для каждого сообщения, а затем запросить и сгруппировать по threadId.
  • Создайте некоторый тип объекта метаинформации, который помогает.

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

+0

Я знаю, что это не то, что вы просили, но: является ли Монго действительно требованием или у вас есть гибкость при выборе хранилища документов? Проблема, которую вы описываете, на самом деле является реляционной ... Если вы можете выбрать другое решение для хранения, я бы предложил OrientDB вместо Mongo, поскольку он может выступать в качестве хранилища документов, и ваши руки не будут привязаны, как сейчас. , Независимо от того, что вы решили пойти, я предлагаю вам запустить определенные тесты, чтобы убедиться, что ваши ожидания соответствуют реальной производительности! – easuter

+0

@easuter. Спасибо за ответ. Я рад использовать реляционный db, но я не думаю, что он решит проблему. Можете ли вы рассказать о том, как поможет реляционная модель? – Jakobovski

+0

Во-первых, извините за задержку в ответе! Хранилища документов, такие как Mongo, великолепны, если вы храните строго иерархические данные, и когда вы уверены, что ваша схема (heh ...) будет статичной навсегда. Классическим примером этой проблемы было [первоначальное использование Diaspora MongoDB в качестве хранилища проекта] (http://tinyurl.com/mzux7tq), я очень рекомендую его прочитать. Возвращаясь к этому последнему пункту: вы не знаете наверняка, изменится ли в будущем ваши требования клиента, и к тому времени вы можете «закодировать себя в угол», сделав переход на что-то еще очень болезненным. – easuter

ответ

-1

Положите threadId на свои сообщения.

Результаты поиска, объединенные в сообщение нить.

Вы можете найти сообщения по теме, как

db.messages.find({ "threadId" : id }) 

Я не думаю, что есть какая-либо необходимость сгруппировать их в смысле оператора $group.

Хорошо работать с разбиением на страницы.

Pagination для сообщений в каком порядке? Pagination работает хорошо, если у вас есть сортировка на уникальном поле. dateSent должен быть уникальным, если вы сохраните его до миллисекундной точности, чтобы вы могли рисовать на нем.

// page 1 
db.messages.find({ "threadId" : id }).sort({ "dateSent" : -1 }).limit(25) 
// page 2 
db.messages.find({ "threadId" : id, "dateSent" : { "$gt" : <25th date sent> } }).sort({ "dateSent" : -1 }).limit(25) 

Сортируемый по дате и теме.

Кто сортирует сообщения по теме? Во всяком случае, это всего лишь вопрос создания правильных индексов, если вы хотите получать сообщения в дате или порядке.В зависимости от ваших требований вы можете выполнять эту сортировку для представления клиента, где может быть необязательно, чтобы база данных сортировала результаты. Клиент мог бы сделать это для возвращаемого подмножества.

+1

Это не будет работать. Ваш запрос будет возвращать сообщения, но они не будут сгруппированы по потоку. Если 25 самых последних сообщений принадлежат одному и тому же потоку, то он просто вернет сообщения из 1 потока, а не 25 потоков. Входящие должны показывать 25 потоков не 1. – Jakobovski

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