Пространственный поиск Elasticsearch по терминам

Я выполняю запрос к более чем 140 миллионам документов с пространственными данными. Чисто пространственные запросы выполняются очень быстро (менее единицы). Добавление подстановочного знака к той же геометрии приводит к тому, что запрос занимает ~ 10-20 секунд. Я ожидаю, что запросы с подстановочными знаками займут некоторое время, но я хочу знать, есть ли лучший способ написать запрос или обмануть Elasticsearch, чтобы отфильтровать результаты только по геометрии, а затем найти совпадения с подстановочными знаками. Или, может быть, запустить пространственный запрос, а затем запустить подстановочный знак для результирующих идентификаторов документов? Мы будем признательны за любые идеи, которые могут привести к более быстрым результатам для конечного пользователя.

GET parcels/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "wildcard": {
            "name.keyword": {
              "value": "*smith*"
            }
          }
        },
        {
          "bool": {
            "filter": [
              {
                "geo_shape": {
                  "shape": {
                    "shape": {
                      "type": "POLYGON",
                      "coordinates": [
                        [
                          [
                            -81.09980486601305,
                            32.063655184739936
                          ],
                          [
                            -81.09980486601168,
                            32.05639855631687
                          ],
                          [
                            -81.09128330779276,
                            32.05639855631687
                          ],
                          [
                            -81.09128330779276,
                            32.06365489826756
                          ],
                          [
                            -81.09980486601305,
                            32.063655184739936
                          ]
                        ]
                      ]
                    },
                    "relation": "intersects"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  },
  "size": 10000
}

наши настройки для индекса:

{
...
"analysis": {
    "normalizer": {
        "search_normalizer": {
            "filter": [
                "uppercase"
            ],
            "type": "custom"
         }
     }
},
"number_of_shards": 8,
"number_of_replicas": 1,

отображение для поля "имя":

"name": {
    "type": "text",
    "fields": {
        "keyword": {
            "type": "keyword",
            "normalizer": "search_normalizer"
        }
    }
},

Запуск ES 7.10. (5 узлов каждый с 8 ГБ ОЗУ)

Отказ от поиска по подстановочному знаку не вариант.

Любая помощь приветствуется.


person Adam Bolfik    schedule 15.02.2021    source источник


Ответы (1)


Использование подстановочного поиска с подстановочным знаком префикса (как в *smith*) в поле keyword снижает производительность!

Если вам абсолютно необходимы такие функции, вам необходимо использовать новый _ 3_ тип поля, который предназначен именно для такого использования.

Таким образом, вы можете либо добавить другое подполе, либо изменить подполе keyword на подполе «подстановочный знак».

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

person Val    schedule 15.02.2021
comment
Не уверен, как я пропустил эту замечательную функцию в примечаниях к выпуску ... Спасибо! Я попробую. - person Adam Bolfik; 15.02.2021
comment
Я протестировал это на подмножестве данных, и это было серьезное улучшение (~ 5x). Мне пришлось добавить параметр недокументированный case_insensitive, чтобы воспроизвести текущую функциональность. Я брошу его против полного набора данных после повторного индексирования. Спасибо еще раз. - person Adam Bolfik; 15.02.2021
comment
Потрясающе, рад, что это привело к значительным улучшениям! - person Val; 15.02.2021