Монго индексация массивов объектов против объектов - PullRequest
28 голосов
/ 06 марта 2012

Я реализую базу данных контактов, которая обрабатывает довольно много полей. Большинство из них предопределены и могут считаться связанными, но есть пара, которые этого не делают. Мы назовем одно из этих полей «группами». В настоящее время мы реализуем его так (у каждого документа / контакта есть поле 'groups'):

'groups' : {
   152 : 'hi',
   111 : 'group2'
}

но после некоторого прочтения я, кажется, должен был это сделать:

'groups' : [
   { 'id' : 152, 'name' : 'hi' },
   { 'id' : 111, 'name' : 'group2' }
   ...
]

, а затем применить индекс db.contact.ensureIndex({'groups.id':1});

Мой вопрос касается функциональности. Каковы различия между этими 2 структурами и как фактически создается индекс (это просто индексирование в каждом документе / контакте или создание полномасштабного индекса, в котором есть все группы из всех документов / контактов?).

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

1 Ответ

47 голосов
/ 07 марта 2012

Запросы, безусловно, будут намного проще во втором случае, где «groups» - это массив поддокументов, каждый из которых имеет «id» и «name».

Mongo не поддерживает «подстановочные» запросы, поэтому, если ваши документы были структурированы первым способом, и вы хотели найти поддокумент со значением «hi», но не знали, что ключ был 152,Вы не сможете сделать это.Со второй структурой документа вы можете легко запросить {"groups.name": "hi"}.

Для получения дополнительной информации о запросах встроенных объектов см. Документацию под названием «Точечная нотация (доступ к объектам)» * http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29 Разделы «Значение в массиве» и «Значение во встроенном объекте»документации «Расширенные запросы» также полезны: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-ValueinanArray

Для индекса {'groups.id': 1} будет создана запись индекса для каждого ключа «id» в каждой «группе»."массив в каждом документе.С индексом "groups" будет создана только одна запись индекса для каждого документа.

Если у вас есть документы второго типа и индекс по группам, ваши запросы должны будут соответствовать целым поддокументам, чтобы использовать индекс.Например, для данного документа:

{ "_id" : 1, "groups" : [ { "id" : 152, "name" : "hi" }, { "id" : 111, "name" : "group2" } ] }

Запрос

db.<collectionName>.find({groups:{ "id" : 152, "name" : "hi" }}) 

будет использовать индекс, но запросы

db.<collectionName>.find({"groups":{$elemMatch:{name:"hi"}}})

или

db.<collectionName>.find({"groups.name":"hi"})

не будет.

Индекс (ы), который вы создаете, должен зависеть от того, какие запросы вы будете выполнять чаще всего.

Вы можете поэкспериментировать, с какими (если они есть) индексами, используемыми вашими запросами, с помощью команды .explain ().http://www.mongodb.org/display/DOCS/Explain Первая строка, «курсор», сообщит вам, какой индекс используется.«курсор»: «BasicCursor» указывает, что выполняется полное сканирование коллекции.

Дополнительная информация по индексированию приведена в документации: http://www.mongodb.org/display/DOCS/Indexes

В разделе «Элементы индексации массива» приведенных выше ссылок на документ под названием «Multikeys»: http://www.mongodb.org/display/DOCS/Multikeys

Надеюсь, это улучшит ваше понимание того, как запрашивать встроенные документы и как используются индексы.Пожалуйста, дайте нам знать, если у вас есть дополнительные вопросы!

...