2014-09-29 3 views
0

У меня очень большая коллекция (более 800k), и мне нужно реализовать запрос для автозаполнения (основанный только на словах) функциональности на основе тегов. мои документы выглядеть следующим образом:mongodb fast tags query

{ 
    "_id": "theid", 
    "somefield": "some value", 
    "tags": [ 
     { 
      "name": "abc tag1", 
      "vote": 5 
     }, 
     { 
      "name": "hij tag2", 
      "vote": 22 
     }, 
     { 
      "name": "abc tag3", 
      "vote": 5 
     }, 
     { 
      "name": "hij tag4", 
      "vote": 77 
     } 
    ] 
} 

если, например, мой запрос будет для всех тегов, которые начинаются с «AB» и имеют «SomeField», то есть «некоторое значение» результат будет «а tag1», «abc tag3» (только имена). Меня волнует скорость запросов намного больше, чем скорость вставок и обновлений.

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

документы не являются документами «тега», они являются документами, представляющими объект-клиент, они содержат гораздо больше полей данных, которые я забыл для простоты, каждый клиент имеет несколько тегов и другое поле (я изменил его имя, чтобы оно не было путают с массивом меток). Мне нужно получить набор без дубликатов всех тегов, которые есть у группы клиентов.

+0

Я попытался сделать что-то подобное в прошлом году, но с гораздо меньшей базой данных. В итоге мне пришлось использовать Solr по мере роста объема данных. – Martin

+0

можете ли вы отправить запрос и индексы, которые вы пробовали? Вы использовали структуру агрегации? – jacob

+0

Простите, код давно ушел, но он был основан на регулярных выражениях в поле тега. Он предписывает структуру агрегации, но я не уверен, что это был бы наилучший подход. По моему опыту, структура агрегации любит читать целые документы в памяти, даже если совпадение $ могло быть сделано с использованием только индекса – Martin

ответ

0

Ваша структура документа не имеет смысла - я предполагаю, что tags - это массив, а не объект. Попробуйте запросы, как этот

db.tags.find({ "somefield" : "some value", "tags.name" : /^abc/ }) 

с индексом на { "maintag" : 1, "tags.name" : 1 }. MongoDB оптимизирует запросы с регулярным выражением с левым якорем в запросах диапазона, которые могут быть эффективно выполнены с использованием индекса (см. $regex docs).

Вы можете получить только тег из этого документа структуры с использованием трубопровода агрегации:

db.tags.aggregate([ 
    { "$match" : { "somefield" : "some value", "tags.name" : /^abc/ } }, 
    { "$unwind" : "$tags" }, 
    { "$match" : { "tags.name" : /^abc/ } }, 
    { "$project" : { "_id" : 0, "tag_name" : "$tags.name" } } 
]) 

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

+0

, вы были правы, я ошибся в своем объекте, я его исправил. ваш запрос вернет все документы, которые соответствуют условию, мне нужен только список тегов, которые не будут дублироваться. в противном случае я выберу лишние ненужные данные. – jacob

+0

Оператор $ positional может проецировать 1 соответствующий тег. Если вам действительно нужно вернуть все теги, вы структурировали свои документы ненадлежащим образом. Документы должны быть тегами с основным помеченным в них тегом вместо основного документа тега с прикрепленными тегами. – wdberkeley

+0

Я думаю, что я не был ясно в своем вопросе, пожалуйста, см. Мое редактирование. его не документ тега, его клиентский документ с вложенным деморализованным массивом тегов. – jacob