Как изменить тип поля в индексе ElasticSearch?

#elasticsearch #kibana

#elasticsearch #kibana

Вопрос:

У меня есть index_A, который включает числовое поле «foo».

Я копирую сопоставление для index_A и вызываю dev tools PUT /index_B с полем foo, измененным на text, поэтому часть сопоставления этого:

«foo»: { «тип»: «текст», «поля»: { «ключевое слово»: { «тип»: «ключевое слово» } }

Затем я переиндексирую index_A в index_B с помощью:

 POST _reindex
{
  "source": {
    "index": "index_A"
  },
  "dest": {
    "index": "index_B"
  }
}
 

Когда я перехожу к просмотру любого документа для index_B, запись для поля «foo» по-прежнему является числом. (Я ожидал, например: «foo»: 30 станет «foo»: «30» в источнике нового документа).

Сколько бы я ни читал о сопоставлениях и переиндексации, я все еще не понимаю, как это сделать. Что конкретно мне нужно выполнить, чтобы получить этот новый индекс с «foo» в качестве текстового поля, а все числовые записи для foo в исходном индексе были изменены на текстовые записи в новом индексе?

Ответ №1:

Существует различие между тем, как поле хранится и индексируется в ES. То, что вы видите внутри _source , сохраняется, и это «оригинальный» документ, который вы проглотили. Но нет явного приведения на основе типа сопоставления — ES сохраняет то, что он получает, но затем продолжает индексировать его, как определено в сопоставлении.

Чтобы проверить, как было проиндексировано поле, вы можете проверить стек скриптов, возвращаемый в:

 GET index_b/_search
{
  "script_fields": {
    "debugging_foo": {
      "script": {
        "source": "Debug.explain(doc['foo'])"
      }
    }
  }
}
 

в отличие от того, как поле было сохранено:

 GET index_b/_search
{
  "script_fields": {
    "debugging_foo": {
      "script": {
        "source": "Debug.explain(params._source['foo'])"
      }
    }
  }
}
 

Другими словами, будьте уверены, что foo это действительно было проиндексировано как text keyword .

Если вы хотите явно преобразовать значение поля в другой тип данных в _source , вы можете применить сценарий в соответствии с:

 POST _reindex
{
  "source": {
    "index": "index_a"
  },
  "dest": {
    "index": "index_b"
  },
  "script": {
    "source": "ctx._source.foo = ''   ctx._source.foo"
  }
}
 

Я не слишком хорошо знаком с Java, но я думаю ... = ctx._source.foo.toString() , что это тоже сработает.


К вашему сведению, есть coerce параметр сопоставления, который звучит так, как будто он может быть полезен здесь, но он работает только наоборот — преобразование / синтаксический анализ из строк в числовые типы и т.д.


К вашему сведению # 2 Есть конвейерный процессор, convert который выполняет именно то, что я сделал в приведенном выше сценарии, и даже больше. (Конвейер — это препроцессор, который запускается до того, как поля будут проиндексированы в ES.) Хорошая особенность конвейеров в том, что их тоже можно запускать как часть _reindex процесса.