Как искать амперсанд в Elasticsearch?
В Elasticsearch, как искать значение с амперсандом? Пытался:
http://localhost:9200/my_index/_search?q=name:"procter \u0026 gamble"
1 ответ
Существуют различные способы, но один из способов будет объявить вашу строку как not_analyzed
в вашем отображении (см. ниже), а затем найдите точное значение, которое было проиндексировано.
curl -XPUT localhost:9200/tests -d '{
"mappings": {
"test": {
"properties": {
"name": {
"type": "string",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}'
Теперь мы индексируем образец документа:
curl -XPUT localhost:9200/tests/test/1 -d '{"name":"procter & gamble"}'
И, наконец, ваш поисковый запрос вернет ожидаемый вами документ:
curl -XGET localhost:9200/tests/test/_search?q=name.raw:"procter %26 gamble"
ОБНОВЛЕНИЕ Вот еще один более сложный способ использования nGram
токенайзер, который будет индексировать все возможные токены длиной от 2 до 20 (произвольный выбор) ваших имен.
curl -XPUT localhost:9200/tests -d '{
"settings": {
"analysis": {
"analyzer": {
"ngram_analyzer": {
"tokenizer": "ngram_tokenizer",
"filter": [
"lowercase"
]
}
},
"tokenizer": {
"ngram_tokenizer": {
"type": "nGram",
"min_gram": 2,
"max_gram": 20
}
}
}
},
"mappings": {
"test": {
"properties": {
"name": {
"type": "string",
"index_analyzer": "ngram_analyzer",
"search_analyzer": "keyword"
}
}
}
}
}'
Тогда вы можете искать точное имя, как раньше
curl -XGET localhost:9200/tests/test/_search?q=name:"procter %26 gamble"
Или просто с помощью какого-нибудь жетона на ваше имя
curl -XGET localhost:9200/tests/test/_search?q=name:procter
curl -XGET localhost:9200/tests/test/_search?q=name:"procter %26"
curl -XGET localhost:9200/tests/test/_search?q=name:gamble
Я использовал немного другой подход. Создайте собственный анализатор шаблонов со специальными символами (я использовал &'-@).
Исходный анализатор образов в ES - "\W+"
Начиная с документации ES: https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-pattern-analyzer.html
Анализатор шаблонов использует регулярное выражение для разделения текста на термины. Регулярное выражение должно соответствовать разделителям токенов, а не самим токенам. Регулярное выражение по умолчанию имеет значение \W+ (или все несловарные символы).
Поэтому, чтобы добавить специальные символы, которые я хотел, мне пришлось инвертировать логику этого регулярного выражения. Это мой пользовательский анализатор.
"special_chars_analyzer": {
"type": "pattern",
"pattern": "[^\\w&'-@]+",
"lowercase": true
}