Странное поведение запроса диапазона в Elasticsearch - PullRequest
1 голос
/ 07 августа 2020

Мой вопрос довольно простой. У меня есть индекс ES, который содержит поле updated, которое является отметкой времени UNIX. У меня есть только тестовые записи (документы) в моем индексе, которые были созданы сегодня .

У меня есть следующий запрос, который работает хорошо и (правильно) не работает 'не возвращает никаких результатов при выполнении:

GET /test_index/_search
{
  "size": 1,
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "updated": {
              "lt": "159525360"
            }
          }
        }
      ]
    }
  },
  "sort": [
    {
      "updated": {
        "order": "desc",
        "mode": "avg"
      }
    }
  ]
}

Так что все в порядке. Однако, когда я меняю метку времени в своем запросе на меньшее число, я получаю несколько результатов! И все эти результаты содержат гораздо большие значения в поле updated, чем 5000! Что еще более озадачивает, я получаю результаты, когда updated устанавливается только в диапазоне от 1971 до 9999. Так что числа вроде 1500 или 10000 ведут себя корректно, и я не вижу результатов. Ниже показано странное поведение запроса.

GET /test_index/_search
{
  "size": 100,
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "updated": {
              "lt": "5000"
            }
          }
        }
      ]
    }
  },
  "sort": [
    {
      "updated": {
        "order": "desc",
        "mode": "avg"
      }
    }
  ]
}

Кстати, вот как выглядит мой типичный документ, хранящийся в этом индексе:

{
    "_index" : "test_index",
    "_type" : "_doc",
    "_id" : "V6LDyHMBAUKhWZ7lxRtb",
    "_score" : null,
    "_source" : {
      "councilId" : 111,
      "chargerId" : "15",
      "unitId" : "a",
      "connectorId" : "2",
      "status" : 10,
      "latitude" : 77.7,
      "longitude" : 77.7,
      "lastStatusChange" : 1596718920,
      "updated" : 1596720720,
      "dataType" : "recorded"
    },
    "sort" : [
      1596720720
    ]
}

Вот отображение этого индекса:

PUT /test_index/_mapping
{
    "properties": {
        "chargerId":  { "type": "text"},
        "unitId":  { "type": "text"},
        "connectorId":  { "type": "text"},
        "councilId": { "type": "integer"},
        "status": {"type": "integer"},
        "longitude" : {"type": "double"},
        "latitude" : {"type": "double"},
        "lastStatusChange" : {"type": "date"},
        "updated": {"type": "date"}
    }
}

Есть ли этому объяснение?

1 Ответ

2 голосов
/ 07 августа 2020

Формат по умолчанию для поля даты в ES - strict_date_optional_time||epoch_millis. Поскольку вы не указали epoch_second, ваши даты были неправильно проанализированы (считались миллисекундами с эпохи). Это можно проверить, запустив этот скрипт:

GET test_index/_search
{
  "script_fields": {
    "updated_pretty": {
      "script": {
        "lang": "painless",
        "source": """
          LocalDateTime.ofInstant(
             Instant.ofEpochMilli(doc['updated'].value.millis),
             ZoneId.of('Europe/Vienna')
          ).format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"))
          """
      }
    }
  }
}

Быстрое исправление: обновите отображение следующим образом:

{
  ...
  "updated":{
    "type":"date",
    "format":"epoch_second"
  }
}

и переиндексируйте.

...