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

Elasticsearch: найдите подстроку

Я хочу выполнить как точное совпадение слов, так и частичное совпадение слов/подстрок. Например, если я ищу "бритву для мужчин" , тогда я смогу найти "бритву для мужчин" в результате. Но в случае, если я искал "en shaver", тогда и я должен был бы найти "бритву для мужчин" в результате. Я использую следующие настройки и отображения:

Настройки индекса:

PUT /my_index
{
    "settings": {
        "number_of_shards": 1, 
        "analysis": {
            "filter": {
                "autocomplete_filter": { 
                    "type":     "edge_ngram",
                    "min_gram": 1,
                    "max_gram": 20
                }
            },
            "analyzer": {
                "autocomplete": {
                    "type":      "custom",
                    "tokenizer": "standard",
                    "filter": [
                        "lowercase",
                        "autocomplete_filter" 
                    ]
                }
            }
        }
    }
}

Отображение:

PUT /my_index/my_type/_mapping
{
    "my_type": {
        "properties": {
            "name": {
                "type":            "string",
                "index_analyzer":  "autocomplete", 
                "search_analyzer": "standard" 
            }
        }
    }
}

Вставить записи:

POST /my_index/my_type/_bulk
{ "index": { "_id": 1            }}
{ "name": "men shaver" }
{ "index": { "_id": 2            }}
{ "name": "women shaver" }

Query:

1. Поиск по точному совпадению фразы → "мужской"

POST /my_index/my_type/_search
{
    "query": {
        "match": {
            "name": "men's"
        }
    }
}

Выше запроса возвращает "бритва для мужчин" в возвращаемом результате.

2. Для поиска по партиальному совпадению слов → "en's"

POST /my_index/my_type/_search
{
    "query": {
        "match": {
            "name": "en's"
        }
    }
}

Выше запрос НЕ возвращает ничего.

Я также пробовал следующий запрос

POST /my_index/my_type/_search
{
    "query": {
        "wildcard": {
           "name": {
              "value": "%en's%"
           }
        }
    }
}

По-прежнему ничего не получается. Я понял, что это из-за фильтра типа "edge_ngram" на Index, который не может найти "частичное совпадение слов /sbustring ". Я попробовал фильтр типа "n-gram", но он замедляет поиск.

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

4b9b3361

Ответ 1

Для поиска парциальных совпадений полей и точных совпадений он будет работать лучше, если вы определяете поля как "не проанализированные" или как ключевые слова (а не текст), а затем используйте подстановочный запрос.

См. также это.

Чтобы использовать подстановочный запрос, добавьте * на обоих концах строки, которую вы ищете:

POST /my_index/my_type/_search
{
"query": {
    "wildcard": {
       "name": {
          "value": "*en's*"
       }
    }
}
}

Чтобы использовать с нечувствительностью к регистру, используйте собственный анализатор с нижним фильтром и ключевым словом tokenizer.

Пользовательский анализатор:

"custom_analyzer": {
            "tokenizer": "keyword",
            "filter": ["lowercase"]
        }

Сделать строку поиска строчной строкой

Если вы получите строку поиска AsD: измените ее на * asd *

Ответ 2

Поиск с помощью любой строки или подстроки Использование:

query: {
    or: [{
      match_phrase_prefix: {
            name: str
     }
    }, {
        match_phrase_prefix: {
            surname: str
        }
    }]
}

Счастливое кодирование с помощью Elastic Search....