Эластичный поиск: как искать строку, начинающуюся с некоторых символов

#elasticsearch

#elasticsearch

Вопрос:

Я хотел выполнить поиск данных из эластичного поиска, где данные совпадают с начала первых n символов.

ниже приведен набор данных / данные, которые у меня есть в индексе ES

 {
    "took": 0,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 47,
            "relation": "eq"
        },
        "max_score": 1,
        "hits": [
            {
                "_index": "search_suggestions",
                "_type": "_doc",
                "_id": "VW5pdGVkIFN0YXRlcw==",
                "_score": 1,
                "_source": {
                    "id": "VW5pdGVkIFN0YXRlcw==",
                    "name": "India",
                    
                }
            },
            {
                "_index": "search_suggestions",
                "_type": "_doc",
                "_id": "RW1iYXNzeSBvZiB0aGUgViwgREMsIFVTQQ==",
                "_score": 1,
                "_source": {
                    "id": "RW1iYXNzeSBvZiB0aGUgViwgREMsIFVTQQ",
                    "name": "Maharashtra, India",
                }
            },
            {
                "_index": "search_suggestions",
                "_type": "_doc",
                "_id": "TWFoaSBCYXpB",
                "_score": 1,
                "_source": {
                    "id": "TWFoaSBCYXpB",
                    "name": "Pune, Maharashtra, India",
                 }
            }
        ]
    }
}
 

Я пробовал поиск с использованием методов запроса / термина / префикса / подстановочного знака. Я хотел найти имена, начинающиеся с «Ind *», но в ответ он возвращает строки, которые совпадают в любом месте строки. Я хотел, чтобы результаты начинались только с «Ind *», только я должен получить «India» в качестве результата, а не другие.

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

Ответ №1:

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

Анализ API

 {
  "analyzer" : "standard",
  "text" : "Maharashtra, India"
}
 

Генерируются следующие токены:

 {
  "tokens": [
    {
      "token": "maharashtra",
      "start_offset": 0,
      "end_offset": 11,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "india",
      "start_offset": 13,
      "end_offset": 18,
      "type": "<ALPHANUM>",
      "position": 1
    }
  ]
}
 

Для достижения вашего варианта использования вам необходимо установить name поле как keyword поле типа

Сопоставление индексов:

 {
  "mappings": {
    "properties": {
      "name": {
        "type": "keyword"
      }
    }
  }
}
 

Поисковый запрос:

 {
  "query": {
    "prefix": {
      "name": {
        "value": "Ind"
      }
    }
  }
}
 

Результат поиска:

 "hits": [
      {
        "_index": "65119778",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.0,
        "_source": {
          "id": "VW5pdGVkIFN0YXRlcw==",
          "name": "India"
        }
      }
    ]
 

Комментарии:

1. Поддерживает ли ‘prefix’ специальные символы?