Подтвердить что ты не робот

Индексирование Mongo на объектных массивах против объектов

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

Mongo не поддерживает "подстановочные" запросы, поэтому, если ваши документы были структурированы первым способом, и вы хотели найти поддокумент со значением "привет", но не знали, что ключ был 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"})

не будет.

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

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

В документации больше информации об индексации: http://www.mongodb.org/display/DOCS/Indexes

Раздел "Элементы индексирования массивов" выше ссылается на документ под названием "Multikeys": http://www.mongodb.org/display/DOCS/Multikeys

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