Запрос диапазона на строку [Elasti c Поиск] - PullRequest
1 голос
/ 21 апреля 2020

У меня есть JSON объект с теми же ключами.

Значения могут быть строкой или цифрой c (в виде строки) и индексируются как текст в тот же шаблон в Elasti c search

[{
  "key" : "foo",
  "value" : "lisa"
}, {
  "key" : "bar",
  "value" : "19"
}]

Я сравниваю на основе следующего:

1. match key as "bar"
2. range { "value" : {gt:"10"}}

Этого не происходит, так как значение индексируется как строка (что и должно быть) и поскольку строка «2»> строка «10», ее сбой - что ожидается.

Любые предложения о том, как двигаться вперед для решения этого варианта использования?

Дополнительная информация :

Я вижу, что документация удалена относительно строк, которые будут использоваться в качестве TermRangeQuery в Elasti c Поиск 7.0 +.

Рекомендации :

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html

Ответы [ 2 ]

1 голос
/ 21 апреля 2020

Как вы уже столкнулись, недостаток неправильного типа данных приводит к неожиданному поведению. Я тихо не понял, почему значением может быть либо строка чисел c и c. Но, учитывая вариант использования, я бы предложил определить другое поле для другого типа значения. Учитывая запрос, который вы пытаетесь сопоставить, требует сохранения отношения между ключом и полем значения. Поэтому я бы предложил вам определить вложенное поле вместо простого поля объекта.

Причина неиспользования поля объекта заключается в том, что elastisearch выравнивает объект, а затем индексирует его. Уплощение объекта приводит к потере связи между свойствами. Подробнее об этом здесь .

Теперь рассмотрим следующий пример (elasti c 7.x):

Шаг 1: Определите отображение с правильным типом для полей

PUT test
{
  "mappings": {
    "properties": {
      "nestedField": {
        "type": "nested",
        "properties": {
          "key": {
            "type": "keyword"
          },
          "stringValue": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword"
              }
            }
          },
          "numericValue": {
            "type": "integer"
          }
        }
      }
    }
  }
}

Мы создали nestedField с полями key, stringValue, numericValue типа keyword (не проанализировано), text (стандарт по умолчанию) анализатор и подполе ключевого слова типа, если требуется точное совпадение), integer соответственно.

Шаг 2 : индексный документ

PUT test/_doc/1
{
  "nestedField": [
    {
      "key": "foo",
      "stringValue": "lisa"
    },
    {
      "key": "bar",
      "numericValue": 19
    }
  ]
}

PUT test/_doc/2
{
  "nestedField": [
    {
      "key": "foo",
      "stringValue": "mary"
    },
    {
      "key": "bar",
      "numericValue": 9
    }
  ]
}

Обратите внимание, как я проиндексировал строку значение и число c значение.

Шаг 3: Запрос по мере необходимости.

Для запроса в поле вложенного типа необходимо использовать вложенный запрос .

GET test/_search
{
  "query": {
    "nested": {
      "path": "nestedField",
      "query": {
        "bool": {
          "filter": [
            {
              "term": {
                "nestedField.key": "bar"
              }
            },
            {
              "range": {
                "nestedField.numericValue": {
                  "gt": 10
                }
              }
            }
          ]
        }
      }
    }
  }
}

Приведенный выше запрос вернет только do c 1 , поскольку для do c 2 даже при наличии key: bar, но соответствующее значение (numericValue) не превышает 10.

0 голосов
/ 21 апреля 2020

Из множества Stack-overflow / Github и других ресурсов он подтверждает, что эта функция недоступна для текста.

Единственный способ ее использования - наличие соответствующего поля цифры c при индексации:

[
 { "key" : "foo", "value" : "lisa" }, 
 { "key" : "bar", "value" : "19", "numericValue" : 19}
] 



и индекс на основе числового значения c. Позже используйте это при получении от ES.

1. match key as "bar"
2. range { "numericValue" : {gt:10}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...