В моем индексе есть вложенное поле, содержащее несколько объектов.

 "customFields" : [
            {
              "objectTypeId" : 17,
              "Value" : "",
              "description" : "The original author of the document",
              "Name" : "Document Author"
            },
            {
              "objectTypeId" : 17,
              "Value" : "",
              "description" : "Source document number",
              "Name" : "Legacy document number"
            },
.
.
.
]

Я хочу создать сценарий, который может перемещать поля из объекта customFields в отдельные объекты, например:

"Document_Author": {
"Description": "The original author of the document",
"Value": "Some value"
"ObjectTypeId": 17
},

"Legacy document number": {
"Description": "Source document number",
"Value": "Some value"
"ObjectTypeId": 17
},
.
.
.

Я пробовал такой сценарий, я новичок в эластичном поиске и написании сценариев, поэтому это не работает.

POST /new_document-20/_update_by_query
 {
  "script" : { "inline": "for (int i = 0; i < ctx._source.customFields.length; ++i) { ctx._source.add(\"customFields[i].Name\" : { \"Value\" : \"customFields[i].Value\", \"Description\" : \"customFields[i].description\", \"objectTypeId\" : \"customFields[i].objectTypeId\"}) }",
 
       "query": {
         "bool": {
           "must": [
             {
               "exists": {
                 "field": "customFields.Name"
          }
        }
      ]
    }
  }
  }
}

Я получаю ошибки компиляции из-за этого, указывая на customFields[i].Name, например:

"error": {
    "root_cause": [
      {
        "type": "script_exception",
        "reason": "compile error",
        "script_stack": [
          "... d(\"customFields[i].Name\" : { \"Value\" : \"customFiel ...",
          "                             ^---- HERE"

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

0
Sander Marx 16 Мар 2021 в 01:47

1 ответ

Лучший ответ

Вы можете выполнить только одну ctx._source операцию записи на цикл, чтобы предотвратить ошибку "The maximum number of statements that can be executed in a loop has been reached.".

С учетом сказанного, я предлагаю:

  1. скопировать оригинал _source
  2. извлечь список customFields
  3. повторить извлеченный список и настроить хэш-карты, чтобы они соответствовали желаемому формату
  4. установите вновь сформированную хеш-карту на скопированный source
  5. полностью заменить исходный _source

В практическом плане:

POST /new_document-20/_update_by_query
{
  "script": {
    "inline": """
      def source_copy = ctx._source;
      def customFields = source_copy.remove('customFields');
      
      for (int i = 0; i < customFields.length; i++) {
        // store the current iteratee
        def current = customFields[i];
        
        // remove AND return the name
        def name = current.remove('Name');
        
        // set in the _source
        source_copy[name] = current;
      }
      
      // replace the original source completely
      ctx._source = source_copy;
    """,
    "query": {
      "bool": {
        "must": [
          {
            "exists": {
              "field": "customFields.Name"
            }
          }
        ]
      }
    }
  }
}

И как строка встроенного скрипта:

"\n      def source_copy = ctx._source;\n      def customFields = source_copy.remove('customFields');\n      \n      for (int i = 0; i < customFields.length; i++) {\n        // store the current iteratee\n        def current = customFields[i];\n        \n        // remove AND return the name\n        def name = current.remove('Name');\n        \n        // set in the _source\n        source_copy[name] = current;\n      }\n      \n      // replace the original source completely\n      ctx._source = source_copy;\n    "

Кстати, Экземпляры хэш-карт в P безболезненно создаются либо с помощью вызова new HashMap, либо с помощью (немного сбивающего с толку) оператора [:], то есть:

def entries_map_without_name = [
   "Value" : current.Value, 
   "Description" : current.description,
   "objectTypeId" : current.objectTypeId
];

P.S. Преобразование вложенного списка объектов в набор хэш-карт, которое вы пытались выполнить, имеет свои преимущества и недостатки, особенно. когда дело доходит до раздутого размера отображения и довольно ограниченных возможностей агрегирования.

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

0
Joe Sorocin 16 Мар 2021 в 15:01