Поиск подстроки в Elastic Search Java

Я работаю с эластичным поиском и пытаюсь найти подстроку внутри поля. Например — поиск строки tac в переполнении стека. Я использую для этого MultiMatchQuery, но он не работает. Вот фрагмент моего кода (first_name — это имя поля).

searchString = "*" + searchString.toLowerCase() + "*";
MultiMatchQueryBuilder mqb = new MultiMatchQueryBuilder("irs", first_name);
mqb.type(MultiMatchQueryBuilder.Type.PHRASE);
BoolQueryBuilder searchQuery = boolQuery();
searchQuery.should(mqb);
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
queryBuilder.withQuery(searchQuery);
NativeSearchQuery query = queryBuilder.build();

Когда я ищу tac, он не возвращает никаких результатов. Когда я ищу стек или переполнение, он возвращает переполнение стека.

Поэтому он ищет точную строку. Я пытался использовать MultiMatchQueryBuilder.Type.PHRASE_PREFIX, но он ищет фразы, начинающиеся с подстроки. Он работает со строками типа stac или overf, но не с tac или tack.

Любые предложения о том, как это исправить?

что он возвращает? как это не работает?

Balázs Németh 10.12.2020 21:30

@BalázsNémeth обновил описание

NikhiR 10.12.2020 21:39
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
433
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Запрос Macth анализируется и применяется тот же анализатор, который применяется во время индексации, я полагаю, вы используете анализатор standard, который сгенерировал следующие токены.

POST http://localhost:9200/_analyze

{
    "text": "stack overflow",
    "analyzer" : "standard"
}

{
    "tokens": [
        {
            "token": "stack",
            "start_offset": 0,
            "end_offset": 5,
            "type": "<ALPHANUM>",
            "position": 0
        },
        {
            "token": "overflow",
            "start_offset": 6,
            "end_offset": 14,
            "type": "<ALPHANUM>",
            "position": 1
        }
    ]
}

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

Токенизатор n-gram может решить проблему.

Пример

Отображение индекса

{
  "settings": {
    "analysis": {
      "filter": {
        "autocomplete_filter": {
          "type": "ngram",
          "min_gram": 1,
          "max_gram": 10
        }
      },
      "analyzer": {
        "autocomplete": { 
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "autocomplete_filter"
          ]
        }
      }
    },
    "index.max_ngram_diff" : 10
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "autocomplete", 
        "search_analyzer": "standard" 
      }
    }
  }
}

Образец индексного документа

{
   "title" :  "stack overflow"
}

И поисковый запрос

{
    "query": {
        "match": {
            "title": "tac"
        }
    }
}

И результат поиска

"hits": [
            {
                "_index": "65241835",
                "_type": "_doc",
                "_id": "1",
                "_score": 0.4739784,
                "_source": {
                    "title": "stack overflow"
                }
            }
        ]
    }

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