match_phrase
и match_phrase_prefix
запросов являются запросами полнотекстового поиска и требуют, чтобы поле данных было типа text
.Он очень сильно отличается от используемого вами типа keyword
, теперь позвольте мне объяснить, что вы можете сделать сейчас и в чем разница.
Можно ли заставить match_phrase_prefix
работать?
Да, вы можете использовать match_phrase_prefix
, если измените тип поля на text
.
Как найти префикс, используя keyword
Поле?
keyword
сохраняется и запрашивается как есть, без какого-либо анализа .Думайте об этом как об одной строке;чтобы найти все документы, которые имеют такое поле с заданным префиксом, достаточно использовать запрос prefix
.
Давайте определим наше отображение и вставим пару документов:
PUT myindex
{
"mappings": {
"_doc": {
"properties": {
"approved_labelled_products": {
"properties": {
"companies": {
"type": "keyword",
"null_value": "NULL",
"ignore_above": 9500
}
}
}
}
}
}
}
POST myindex/_doc
{
"approved_labelled_products": {
"companies": "SOMETHING INC"
}
}
Теперь мы можем выполнить запрос, подобный следующему:
POST myindex/_doc/_search
{
"query": {
"prefix": {
"approved_labelled_products.companies": "SOME"
}
}
}
Обратите внимание, что, поскольку буквальный анализ не выполняется, запрос чувствителен к регистру, и запрос по строке "some"
не вернетрезультаты.
Чем отличается поле text
?
text
поле анализируется во время индексации, что означает, что входная строкаразделение на токены, в нижнем регистре, некоторая метаинформация сохраняется и создается инвертированный индекс .
Это позволяет эффективно извлекать документы, содержащие определенный токен или комбинацию токенов.
Чтобы проиллюстрировать это, мы можем использовать _analyze API .Давайте попробуем посмотреть, как Elasticsearch будет сначала анализировать данные для поля keyword
:
POST _analyze
{
"analyzer" : "keyword",
"text": "SOMETHING INC"
}
Это вернет:
{
"tokens": [
{
"token": "SOMETHING INC",
"start_offset": 0,
"end_offset": 13,
"type": "word",
"position": 0
}
]
}
Как видите, это один токен свсе заглавные буквы.
Теперь давайте посмотрим, что делает анализатор standard
(тот, который поле text
использует по умолчанию):
POST _analyze
{
"analyzer" : "standard",
"text": "SOMETHING INC"
}
Возвращает:
{
"tokens": [
{
"token": "something",
"start_offset": 0,
"end_offset": 9,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "inc",
"start_offset": 10,
"end_offset": 13,
"type": "<ALPHANUM>",
"position": 1
}
]
}
Как видите, он выпустил два токена в нижнем регистре.
Надеюсь, это поможет!