MongoDB - Разница между индексом по текстовому полю и текстовым индексом?

Для поля MongoDB, которое содержит строки (например, имена штатов или провинций), какая (если таковая имеется) разница между созданием индекса в поле типа строки:

db.ensureIndex( { field: 1 } )

и создание текстового индекса в этом поле:

db.ensureIndex( { field: "text" }

Где в обоих случаях field имеет string тип.

Я ищу способ выполнить регистронезависимый поиск по текстовому полю, которое будет содержать одно слово (возможно, больше). Будучи новичком в Mongo, у меня возникли проблемы с разграничением между использованием двух указанных выше методов индекса и даже чем-то вроде $regex поиск.

2 ответа

Решение

Два варианта индекса очень разные.

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

  • Текстовый индекс на другом жестком токене будет разбит и заполнит содержимое поля. Таким образом, он будет разбивать строку на отдельные слова или токены и будет дополнительно сокращать их до их основ, так что варианты одного и того же слова будут совпадать ("говорить", сопоставлять "разговоры", "говорить" и "говорить", например, как " говорить "это основа всех трех). В основном полезно для истинного текста (предложения, абзацы и т. Д.).

    Поиск текста

    Текстовый поиск поддерживает поиск строкового содержимого в документах коллекции. MongoDB обеспечивает $text оператор для выполнения текстового поиска в запросах и в агрегационных конвейерах.

    Процесс поиска текста:

    tokenizes and stems the search term(s) during both the index creation and the text command execution.
    assigns a score to each document that contains the search term in the indexed fields. The score determines the relevance of a document to a given search query.
    

    $text Оператор может искать слова и фразы. Запрос совпадает по полному основному слову. Например, если поле документа содержит слово blueberry, поиск по синему слову не будет соответствовать документу. Тем не менее, поиск по чернике или чернике будет соответствовать.

  • $regex поиск может использоваться с обычными индексами в строковых полях, чтобы обеспечить некоторое сопоставление с образцом и поиск по шаблону. Не очень эффективный пользователь индексов, но он будет использовать индексы там, где он может:

    Если для поля существует индекс, то MongoDB сопоставляет регулярное выражение со значениями в индексе, что может быть быстрее, чем сканирование коллекции. Дальнейшая оптимизация может произойти, если регулярное выражение является "префиксным выражением", что означает, что все потенциальные совпадения начинаются с одной и той же строки. Это позволяет MongoDB построить "диапазон" из этого префикса и сопоставлять только те значения из индекса, которые попадают в этот диапазон.

http://docs.mongodb.org/manual/core/index-text/

http://docs.mongodb.org/manual/reference/operator/query/regex/

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

До MongoDB 2.6 операции текстового поиска должны были выполняться с помощью их собственной команды, что было большим недостатком, поскольку вы не можете ни комбинировать ее с другими фильтрами, ни обрабатывать результат как обычный курсор. На данный момент текстовый поиск является еще одним оператором для типичного find метод, и это супер приятно.

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

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

Обычный индекс для текстового поля, например

db.ensureIndex( { field: 1 } )

будет полезен, только если вы ищете весь текст. Например, он используется для поиска буквенно-цифровых хэшей. Не имеет смысла применять этот вид индексов при хранении текстовых абзацев, фраз и т. Д.

Другие вопросы по тегам