Замена встроенной строки Elasticsearch, похоже, ничего не делает

У нас есть некоторые устаревшие поля в эластичном поисковом индексе, которые вызывают у нас некоторые проблемы, и мы хотели бы выполнить замену строки по всему индексу.

Например, некоторые старые метки времени хранятся в формате 2000-01-01T00:00:00.000+0100, но должны храниться как 2000-01-01T00:00:00.000+01:00.

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

POST /my_index/_update_by_query
{
    "script":
    {
        "lang": "painless",
        "inline": "ctx._source.timestamp = ctx._source.timestamp.replace('+0100', '+01:00')"
    }
}

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

Есть ли способ увидеть статус такого запроса?

Я также пытался создать поисковый запрос для обновления, но безуспешно:

GET /my_index/_search
{
  "query": {
    "query_string": {
      "query": "*0100",
      "allow_leading_wildcard": true,
      "analyze_wildcard": true,
      "fields": ["timestamp"]
    }
  }
}

Который, к сожалению, всегда возвращает пустой набор - не уверен, что может быть не так.

Каким будет правильный способ добиться такого обновления?


person Vojtěch    schedule 07.06.2021    source источник
comment
Вы должны использовать параметр wait_for_completion=false для запуска задачи в фоновом режиме, см. здесь как   -  person Val    schedule 07.06.2021
comment
звучит полезно! не могли бы вы также проверить поисковый запрос? почему это не вернет никаких результатов?   -  person Vojtěch    schedule 07.06.2021
comment
поля даты не анализируются, как текстовые поля, поэтому этот тип запроса (например, запрос с подстановочными знаками) работает   -  person Val    schedule 07.06.2021
comment
Кстати, как выглядит ваше сопоставление для этого поля?   -  person Val    schedule 07.06.2021
comment
сопоставление "timestamp" : { "type" : "date" } — так есть ли способ запросить эти неработающие поля?   -  person Vojtěch    schedule 07.06.2021
comment
Почему ты говоришь, что сломался? Если документы были загружены без ошибок, это означает, что значение соответствует ожидаемому формату даты, т. е. +0100 совпадает с +01:00, оба являются допустимым синтаксисом для часового пояса GMT+1.   -  person Val    schedule 07.06.2021
comment
Наш парсер java требует, чтобы часовой пояс хранился в формате +01:00 вместо +0100, поэтому я хотел бы как-то заменить это в ES.   -  person Vojtěch    schedule 07.06.2021
comment
Я вижу, вы отредактировали комментарий - хотя оба они действительны, синтаксический анализатор Java отказывается их принимать:/   -  person Vojtěch    schedule 07.06.2021


Ответы (1)


Я бы решил эту проблему с помощью конвейера загрузки, который вы будем использовать для обновления всего вашего индекса.

Сначала создайте конвейер загрузки, как показано ниже. Он обнаруживает документы, в которых поле timestamp заканчивается на +0100, а затем обновляет метку времени, чтобы использовать часовой пояс в правильном формате.

PUT _ingest/pipeline/fix-tz
{
  "processors": [
    {
      "dissect": {
        "if": "ctx.timestamp.endsWith('+0100')",
        "field": "timestamp",
        "pattern": "%{timestamp}+%{tz}"
      }
    },
    {
      "set": {
        "if": "ctx.tz != null",
        "field": "timestamp",
        "value": "{{timestamp}}+01:00"
      }
    },
    {
      "remove": {
        "if": "ctx.tz!= null",
        "field": "tz"
      }
    }
  ]
}

Затем, когда конвейер создан, вам просто нужно обновить с его помощью свой индекс, например:

POST my_index/_update_by_query?pipeline=fix-tz&wait_for_completion=false

После того, как это будет выполнено полностью, ваш индекс должен быть правильно обновлен.

person Val    schedule 07.06.2021
comment
Можете ли вы также объяснить, как выполнить запрос типа GET /my_index/_search для таких полей? - person Vojtěch; 07.06.2021
comment
Это не возможно. Существует запрос script, но из соображений производительности он не позволяет получить необработанную строку из ctx._source. - person Val; 07.06.2021