MongoDB полный и частичный текстовый поиск

Env:

  • MongoDB (3.2.0) с MongoS

коллекция:

  • пользователи

создание текстового индекса:

  BasicDBObject keys = new BasicDBObject();
  keys.put("name","text");

  BasicDBObject options = new BasicDBObject();
  options.put("name", "userTextSearch");
  options.put("unique", Boolean.FALSE);
  options.put("background", Boolean.TRUE);

  userCollection.createIndex(keys, options); // using MongoTemplate

документ:

  • {"name": "LEONEL"}

запросы:

  • db.users.find( { "$text" : { "$search" : "LEONEL" } } ) => найти
  • db.users.find( { "$text" : { "$search" : "leonel" } } ) => найдено (поиск чувствителен к регистру false)
  • db.users.find( { "$text" : { "$search" : "LEONÉL" } } ) => найдено (поиск с diacriticSensitive ложь)
  • db.users.find( { "$text" : { "$search" : "LEONE" } } ) => найдено (частичный поиск)
  • db.users.find( { "$text" : { "$search" : "LEO" } } ) => не найдено (частичный поиск)
  • db.users.find( { "$text" : { "$search" : "L" } } ) => Не найдено (частичный поиск)

любая идея, почему я получаю 0 результатов, используя в качестве запроса "LEO"или " L"?

регулярное выражение с поиском текстового индекса не допускается.

db.getCollection('users')
     .find( { "$text" : { "$search" : "/LEO/i", 
                          "$caseSensitive": false, 
                          "$diacriticSensitive": false }} )
     .count() // 0 results

db.getCollection('users')
     .find( { "$text" : { "$search" : "LEO", 
                          "$caseSensitive": false, 
                          "$diacriticSensitive": false }} )
.count() // 0 results

Монго Документация:

1 ответов


Как в MongoDB 3.4,поиск по тексту функция предназначена для поддержки поиска без учета регистра на текстовом содержимом с языковыми правилами для стоп-слов и стволовых. Вытекающие правила поддерживаемые языки основаны на стандартных алгоритмах, которые обычно обрабатывают общие глаголы и существительные, но не знают собственных существительных.

нет явной поддержки частичных или нечетких совпадений, но термины, связанные с аналогичным результатом, могут работать по существу. Например: "вкус", "вкусы", и со вкусом "все стержень к"tast". Попробуйте Snowball Stemming Demo страница для экспериментов с большим количеством слов и алгоритмов stemming.

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

Если вы хотите сделать эффективный частичные совпадения вам нужно будет использовать другой подход. Некоторые полезные идеи см. В разделе:

есть соответствующий запрос на улучшение, который вы можете посмотреть/upvote в трекере MongoDB:SERVER-15090: улучшение текстовых индексов для поддержки частичного слова матч.