Elasticsearch многопольный запрос
У меня проблемы с формированием запроса поиска адреса в ElasticSearch.
Адрес хранится в ES со следующей структурой:
Адрес {улица, город, почтовый индекс}
И вот пример запроса:
GET /adr-address/_search
{
"query": {
"multi_match": {
"query": "mainstreet, houston",
"type": "most_fields",
"fields": [ "street", "city", "zipcode"]
}
}
}
"hits": [
{
"_source": {
"id": "S6v4xyO8UE5NRcWtmMATPQ==",
"street": "Houston 2nd Avenue",
"zipcode": "8032",
"city": "Houston"
}
},
{
"_source": {
"id": "aLgQFrO8zCT8m88lAnYZPQ==",
"street": "Houston 1st Avenue",
"zipcode": "8044",
"city": "Houston"
}
},
{
"_source": {
"id": "aLgQFrO8zCT8m88lAnYZPQ==",
"street": "mainstreet",
"zipcode": "8044",
"city": "Houston"
}
},
Много совпадение запросов работает нормально в большинстве случаев, за исключением сценария, когда улица содержит также название города. Elasticsearch придает более высокий приоритет этим результатам, что вполне понятно, хотя и неприемлемо.
Вот результат _analyze:
GET /adr-address/_validate/query?explain
{
"query": {
"multi_match": {
"query": "mainstreet, houston",
"type": "most_fields",
"fields": [ "street", "city", "zipcode" ]
}
}
}
{
"valid": true,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"explanations": [
{
"index": "adr-address",
"valid": true,
"explanation": "(zipcode:mainstreet zipcode:houston) (street:mainstreet street:houston) (city:mainstreet city:houston)"
}
]
}
Следует отметить, что API Google Maps возвращает точные результаты для того же запроса.
Допущения / условия, сделанные до сих пор:
- Токенайзеры: пробел, запятая, числа и т. Д.
- Вводимый термин может содержать название улицы из нескольких слов, почтовый индекс или город в любом порядке.
Любое предложение о том, как я мог бы улучшить результаты поиска?
1 ответ
Попробуйте использовать cross_fields вместо most_fields в качестве типа для multi_match.
Из документов:
Тип cross_fields особенно полезен для структурированных документов, в которых должны совпадать несколько полей. Например, при запросе полей first_name и last_name для "Will Smith", наилучшее совпадение может иметь "Will" в одном поле и "Smith" в другом.
И большинство используемых вами полей, похоже, предназначены для поиска по одному и тому же тексту, но анализируются по-разному.
Пример запроса:
GET /adr-address/_search
{
"query": {
"multi_match": {
"query": "mainstreet, houston",
"type": "cross_fields",
"fields": [ "street", "city", "zipcode"]
}
}
}