Целочисленное поле автозаполнения Elasticsearch

Я пытаюсь реализовать функцию автозаполнения в числовом поле (фактический тип в ES - long).

Я использую виджет автозаполнения jQuery UI на стороне клиента, имея source функцию, отправляющую запрос в Elasticsearch с префиксом, чтобы получить количество (скажем, 5) вариантов автозаполнения.

Я использую следующий запрос:

{
    "size": 0,
    "query": {
        "prefix": {
            "myField": "<term>"
        }
    },
    "aggs": {
        "myAggregation": {
            "terms": { 
                "field": "myField",
                "size": 5
            }
        }
    }
}

Таким образом, если myField имеет разные значения: [1, 15, 151, 21, 22], а term равно 1, то я ожидал бы получить от ES корзины с ключами [1, 15, 151].

Проблема в том, что это не работает с числовыми полями. В приведенном выше примере я получаю одну корзину с ключом 1, а если term равно 15, я получаю одну корзину с ключом 15, т.е. он возвращает только точные совпадения. Напротив, он отлично работает с string типизированными полями.

Я предполагаю, что мне нужно какое-то специальное сопоставление для myField, но я бы предпочел, чтобы сопоставление было как можно более общим, при этом автозаполнение работало бы с минимальными изменениями сопоставления (просто обратите внимание - индекс, который я запрашиваю, может быть общим one, внешний по отношению к моему приложению, поэтому я смогу изменить отображение типа / поля в нем только в том случае, если новое отображение является чем-то общим и стандартным).

Какие у меня здесь варианты?


person Johan Hirsch    schedule 23.12.2015    source источник


Ответы (1)


Что бы я сделал, так это создать подполе string в вашем целочисленном поле, например:

{
    "myField": {
        "type": "integer",
        "fields": {
            "to_string": {
                "type": "string",
                "index": "not_analyzed"
            }
        }
    }
}

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

{
  "size": 0,
  "query": {
    "prefix": {
      "myField.to_string": "1"
    }
  },
  "aggs": {
    "myAggregation": {
      "terms": {
        "field": "myField",
        "size": 5
      }
    }
  }
}

Обратите внимание, что вы также можете создать полностью независимое поле, не обязательно подполе, ключевым моментом является то, что одному полю требуется целочисленное значение для запуска агрегирования terms, а другому полю требуется строковое значение для выполнения запроса prefix.

person Val    schedule 23.12.2015
comment
Могу ли я после добавления подполя to_string в сопоставление переиндексировать данные? Спасибо! - person Johan Hirsch; 24.12.2015
comment
Да, вам необходимо повторно проиндексировать ваши данные, иначе подполе не будет заполнено. - person Val; 24.12.2015