Elastisearch — как обработать все поля в документе при использовании конвейерного процессора

#elasticsearch

#elasticsearch

Вопрос:

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

    "description": "my pipeline that remvoves empty string and null strings",
   "processors": [
       { 
          "remove": {
              "field": "my_field",
              "ignore_missing": true,
              "if": "ctx.my_field == "null" || ctx.my_field == """
          }
       }
}
  

Ответ №1:

remove Процессор не позволяет использовать подстановочный * знак для проверки всех полей. Вместо этого вы можете выбрать script процессор и сделать это самостоятельно в общем виде:

   {
    "script": {
      "source": """
          // find all fields that contain an empty string or null
          def remove = ctx.keySet().stream()
                          .filter(field -> ctx[field] == "null" || ctx[field] == "")
                          .collect(Collectors.toList());

          // remove them in one go
          for (field in remove) {
            ctx.remove(field);
          }
          """
    }
  }
  

Ответ №2:

Вы можете указать имена полей, разделенных запятыми, или попробовать с * помощью (не уверен, поддерживает ли это, я пытаюсь это сделать), но comma(,) отдельные работы наверняка, как показано в официальном документе

https://www.elastic.co/guide/en/elasticsearch/reference/master/remove-processor.html

 {
  "remove": {
    "field": ["user_agent", "url"]
  }
}
  

Комментарии:

1. Я думаю, что OP хочет удалить все поля без необходимости указывать их все

2. @Elasticsearch Ninja Да, я знаю, что мы можем указывать значения, разделенные запятыми. Но у меня много полей в индексе, поэтому я ищу любые другие, где мне не нужно упоминать все имена полей.

3. @Val, спасибо, да, как упоминал OP, у нее много полей, я думаю, здесь имеет смысл использовать опцию script

Ответ №3:

Полный пример, основанный на принятом ответе, который удаляет все поля с префиксом prefix_ из одного документа / нескольких документов / всех документов. Протестировано с использованием ElasticSearch 6.8.

Единый документ:

 POST /<index>/_doc/<id>/_update
{
  "script": {
    "lang": "painless",
    "source": """
        def fieldsToDelete = ctx._source.keySet().stream()
            .filter(field -> field.startsWith(params.get("prefix")))
            .collect(Collectors.toList());
        fieldsToDelete.stream()
            .forEach(field -> ctx._source.remove(field));
        """,
    "params": {
      "prefix": "prefix_"
    }
  }
}
  

Несколько документов:

 POST /<index>/_update_by_query?conflicts=proceed
{
  "query": {
    <query-based-on-your-requirements>
  },
  "script": {
    "lang": "painless",
    "source": """
        def fieldsToDelete = ctx._source.keySet().stream()
            .filter(field -> field.startsWith(params.get("prefix")))
            .collect(Collectors.toList());
        fieldsToDelete.stream()
            .forEach(field -> ctx._source.remove(field));
        """,
    "params": {
      "prefix": "prefix_"
    }
  }
}
  

Все документы: то же, что и выше, просто опустите query атрибут тела запроса.