Ответ 1
смотрите здесь https://docs.mongodb.com/manual/indexes/#multikey-index
Индекс по полю документа в массиве поддерживается mongodb.
Пример:
{ addr.zip: 1 }
Я пытаюсь найти лучший дизайн для системы обмена сообщениями, которую я переношу с SQL Server на MongoDB - в настоящее время (в SQL Server) есть таблицы деревьев, которые хранят сообщение: Сообщения, Входящие и Отправленные. Сообщение сохраняется в таблице "Сообщения", а "Входящие/Отправленные" имеют записи для всех получателей/отправителей для каждого сообщения.
Теперь, в MongoDB, я хотел объединить эти три в одну коллекцию с такими документами:
{
_id:
subject:
body:
sender: {memid:, name:}
recip: [{memid:, name:}, {memid:, name:}, {memid:, name:}, etc]
}
Теперь мне нужно получить все сообщения для данного получателя memid, и мне нужно сделать это быстро, поэтому необходим индекс (у меня будут сотни миллионов таких записей). Итак, мой вопрос: могу ли я индексировать поле документа в массиве?
смотрите здесь https://docs.mongodb.com/manual/indexes/#multikey-index
Индекс по полю документа в массиве поддерживается mongodb.
Пример:
{ addr.zip: 1 }
Вы можете индексировать суб-ключи в mongo, однако я обнаружил, что производительность индексов на под-ключах в mongoDB довольно плоха, поскольку схемы похожи на то, как вы ее структурировали в вашем примере.
С тем, как у вас есть что-то написанное, похоже, что у вас будет структура в рецепте, которая выглядит так...
array(
'recip' => array(
'0' => array('memid' => 'some_id', 'name' => 'some_name'),
'1' => array('memid' => 'another_id', 'name' => 'another_name'),
'2' => array('memid' => 'yet_another_id', 'name' => 'yet_another_name')
)
)
Фактически вы не сможете установить индекс только для части memip документа с этой структурой, вместо этого вам нужно будет установить весь массив получателей. Это также будет иметь нежелательный побочный эффект индексации имен, а также снова и снова вводить одно и то же ключевое имя, теряя ценную память и вызывая неудовлетворительные запросы.
Я попытался бы структурировать документы таким образом...
array(
'recip' => array(
'memid' => array(
'0' => 'some_id',
'1' => 'another_id',
'2' => 'yet_another_id',
),
'name' => array(
'some_id' => 'some_name',
'another_id' => 'another_name',
'yet_another_id' => 'yet_another_name'
)
)
)
Это образец, который послужил мне хорошим монго. Если вы структурируете документ, как это, вы сможете создать индекс в подмассе recip.memid, не забирая имена. Это, безусловно, будет намного лучше.
Я бы предположил, что у вас будет какое-то поле timestamp, а также для сортировки desc. Еще один индексный лакомый кусочек, который я узнал, заключается в том, что некоторые из драйверов mongo намного лучше выполняют запросы против больших коллекций, если метка времени добавляется как первое поле индекса.
В любом случае вам, скорее всего, придется экспериментировать с вашей схемой и индексировать, прежде чем настраивать свои запросы. Одна из приятных вещей о монго заключается в том, что изменения схемы не так важны.
Удачи с переходом. Я думаю, вам понравится работать с монго, как только вы его повесите.