Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Guide [8.17] ›Отображение ›Поля выполнения

Индексирование поля выполнения

Поля выполнения определяются контекстом, в котором они выполняются. Например, вы можете определить поля выполнения в контексте запроса поиска или в runtime разделе отображения индекса. Если вы решите индексировать поле выполнения для повышения производительности, просто переместите полное определение поля выполнения (включая скрипт) в контекст отображения индекса. Elasticsearch автоматически использует эти индексированные поля для обработки запросов, что приводит к быстрому времени отклика. Эта возможность означает, что вы можете написать скрипт только один раз и применить его к любому контексту, поддерживающему поля выполнения.

Индексирование composite поля выполнения в настоящее время не поддерживается.

Затем вы можете использовать поля выполнения для ограничения количества полей, для которых Elasticsearch должен вычислять значения. Использование индексированных полей совместно с полями выполнения обеспечивает гибкость в данных, которые вы индексируете, и в том, как вы определяете запросы для других полей.

После индексирования поля выполнения вы не можете обновить включённый скрипт. Если вам необходимо изменить скрипт, создайте новое поле с обновлённым скриптом.

Например, предположим, что ваша компания хочет заменить некоторые старые редукционные клапаны. Подключенные датчики способны сообщать только часть истинных показаний. Вместо того, чтобы оснащать редукционные клапаны новыми датчиками, вы решаете вычислять значения на основе сообщённых показаний. На основе сообщённых данных вы определяете следующие поля в своём отображении для my-index-000001:

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "timestamp": {
                "type": "date"
            },
            "temperature": {
                "type": "long"
            },
            "voltage": {
                "type": "double"
            },
            "node": {
                "type": "keyword"
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        timestamp: {
          type: 'date'
        },
        temperature: {
          type: 'long'
        },
        voltage: {
          type: 'double'
        },
        node: {
          type: 'keyword'
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      timestamp: {
        type: "date",
      },
      temperature: {
        type: "long",
      },
      voltage: {
        type: "double",
      },
      node: {
        type: "keyword",
      },
    },
  },
});
console.log(response);
PUT my-index-000001/
{
  "mappings": {
    "properties": {
      "timestamp": {
        "type": "date"
      },
      "temperature": {
        "type": "long"
      },
      "voltage": {
        "type": "double"
      },
      "node": {
        "type": "keyword"
      }
    }
  }
}

Затем вы массово индексируете некоторые образцы данных с ваших датчиков. Эти данные включают voltage показания для каждого датчика:

resp = client.bulk(
    index="my-index-000001",
    refresh=True,
    operations=[
        {
            "index": {}
        },
        {
            "timestamp": 1516729294000,
            "temperature": 200,
            "voltage": 5.2,
            "node": "a"
        },
        {
            "index": {}
        },
        {
            "timestamp": 1516642894000,
            "temperature": 201,
            "voltage": 5.8,
            "node": "b"
        },
        {
            "index": {}
        },
        {
            "timestamp": 1516556494000,
            "temperature": 202,
            "voltage": 5.1,
            "node": "a"
        },
        {
            "index": {}
        },
        {
            "timestamp": 1516470094000,
            "temperature": 198,
            "voltage": 5.6,
            "node": "b"
        },
        {
            "index": {}
        },
        {
            "timestamp": 1516383694000,
            "temperature": 200,
            "voltage": 4.2,
            "node": "c"
        },
        {
            "index": {}
        },
        {
            "timestamp": 1516297294000,
            "temperature": 202,
            "voltage": 4,
            "node": "c"
        }
    ],
)
print(resp)
response = client.bulk(
  index: 'my-index-000001',
  refresh: true,
  body: [
    {
      index: {}
    },
    {
      timestamp: 1_516_729_294_000,
      temperature: 200,
      voltage: 5.2,
      node: 'a'
    },
    {
      index: {}
    },
    {
      timestamp: 1_516_642_894_000,
      temperature: 201,
      voltage: 5.8,
      node: 'b'
    },
    {
      index: {}
    },
    {
      timestamp: 1_516_556_494_000,
      temperature: 202,
      voltage: 5.1,
      node: 'a'
    },
    {
      index: {}
    },
    {
      timestamp: 1_516_470_094_000,
      temperature: 198,
      voltage: 5.6,
      node: 'b'
    },
    {
      index: {}
    },
    {
      timestamp: 1_516_383_694_000,
      temperature: 200,
      voltage: 4.2,
      node: 'c'
    },
    {
      index: {}
    },
    {
      timestamp: 1_516_297_294_000,
      temperature: 202,
      voltage: 4,
      node: 'c'
    }
  ]
)
puts response
const response = await client.bulk({
  index: "my-index-000001",
  refresh: "true",
  operations: [
    {
      index: {},
    },
    {
      timestamp: 1516729294000,
      temperature: 200,
      voltage: 5.2,
      node: "a",
    },
    {
      index: {},
    },
    {
      timestamp: 1516642894000,
      temperature: 201,
      voltage: 5.8,
      node: "b",
    },
    {
      index: {},
    },
    {
      timestamp: 1516556494000,
      temperature: 202,
      voltage: 5.1,
      node: "a",
    },
    {
      index: {},
    },
    {
      timestamp: 1516470094000,
      temperature: 198,
      voltage: 5.6,
      node: "b",
    },
    {
      index: {},
    },
    {
      timestamp: 1516383694000,
      temperature: 200,
      voltage: 4.2,
      node: "c",
    },
    {
      index: {},
    },
    {
      timestamp: 1516297294000,
      temperature: 202,
      voltage: 4,
      node: "c",
    },
  ],
});
console.log(response);
POST my-index-000001/_bulk?refresh=true
{"index":{}}
{"timestamp": 1516729294000, "temperature": 200, "voltage": 5.2, "node": "a"}
{"index":{}}
{"timestamp": 1516642894000, "temperature": 201, "voltage": 5.8, "node": "b"}
{"index":{}}
{"timestamp": 1516556494000, "temperature": 202, "voltage": 5.1, "node": "a"}
{"index":{}}
{"timestamp": 1516470094000, "temperature": 198, "voltage": 5.6, "node": "b"}
{"index":{}}
{"timestamp": 1516383694000, "temperature": 200, "voltage": 4.2, "node": "c"}
{"index":{}}
{"timestamp": 1516297294000, "temperature": 202, "voltage": 4.0, "node": "c"}

После разговора с несколькими инженерами по техническому обслуживанию вы понимаете, что датчики должны сообщать по крайней мере в два раза больше текущих значений, но потенциально и выше. Вы создаёте поле выполнения под названием voltage_corrected, которое извлекает текущее напряжение и умножает его на 2:

resp = client.indices.put_mapping(
    index="my-index-000001",
    runtime={
        "voltage_corrected": {
            "type": "double",
            "script": {
                "source": "\n        emit(doc['voltage'].value * params['multiplier'])\n        ",
                "params": {
                    "multiplier": 2
                }
            }
        }
    },
)
print(resp)
response = client.indices.put_mapping(
  index: 'my-index-000001',
  body: {
    runtime: {
      voltage_corrected: {
        type: 'double',
        script: {
          source: "\n        emit(doc['voltage'].value * params['multiplier'])\n        ",
          params: {
            multiplier: 2
          }
        }
      }
    }
  }
)
puts response
const response = await client.indices.putMapping({
  index: "my-index-000001",
  runtime: {
    voltage_corrected: {
      type: "double",
      script: {
        source:
          "\n        emit(doc['voltage'].value * params['multiplier'])\n        ",
        params: {
          multiplier: 2,
        },
      },
    },
  },
});
console.log(response);
PUT my-index-000001/_mapping
{
  "runtime": {
    "voltage_corrected": {
      "type": "double",
      "script": {
        "source": """
        emit(doc['voltage'].value * params['multiplier'])
        """,
        "params": {
          "multiplier": 2
        }
      }
    }
  }
}

Вы получаете вычисленные значения, используя параметр fields для API _search:

resp = client.search(
    index="my-index-000001",
    fields=[
        "voltage_corrected",
        "node"
    ],
    size=2,
)
print(resp)
response = client.search(
  index: 'my-index-000001',
  body: {
    fields: [
      'voltage_corrected',
      'node'
    ],
    size: 2
  }
)
puts response
const response = await client.search({
  index: "my-index-000001",
  fields: ["voltage_corrected", "node"],
  size: 2,
});
console.log(response);
GET my-index-000001/_search
{
  "fields": [
    "voltage_corrected",
    "node"
  ],
  "size": 2
}

После проверки данных датчиков и проведения некоторых тестов вы определяете, что множитель для сообщённых данных датчика должен быть 4. Чтобы повысить производительность, вы решаете индексировать поле voltage_corrected выполнения с новым параметром multiplier.

В новом индексе под названием my-index-000001 скопируйте определение поля voltage_corrected выполнения в отображение нового индекса. Всё так просто! Вы можете добавить необязательный параметр под названием on_script_error, определяющий, следует ли отклонять весь документ, если скрипт вызовет ошибку во время индексирования (по умолчанию).

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "timestamp": {
                "type": "date"
            },
            "temperature": {
                "type": "long"
            },
            "voltage": {
                "type": "double"
            },
            "node": {
                "type": "keyword"
            },
            "voltage_corrected": {
                "type": "double",
                "on_script_error": "fail",
                "script": {
                    "source": "\n        emit(doc['voltage'].value * params['multiplier'])\n        ",
                    "params": {
                        "multiplier": 4
                    }
                }
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        timestamp: {
          type: 'date'
        },
        temperature: {
          type: 'long'
        },
        voltage: {
          type: 'double'
        },
        node: {
          type: 'keyword'
        },
        voltage_corrected: {
          type: 'double',
          on_script_error: 'fail',
          script: {
            source: "\n        emit(doc['voltage'].value * params['multiplier'])\n        ",
            params: {
              multiplier: 4
            }
          }
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      timestamp: {
        type: "date",
      },
      temperature: {
        type: "long",
      },
      voltage: {
        type: "double",
      },
      node: {
        type: "keyword",
      },
      voltage_corrected: {
        type: "double",
        on_script_error: "fail",
        script: {
          source:
            "\n        emit(doc['voltage'].value * params['multiplier'])\n        ",
          params: {
            multiplier: 4,
          },
        },
      },
    },
  },
});
console.log(response);
PUT my-index-000001/
{
  "mappings": {
    "properties": {
      "timestamp": {
        "type": "date"
      },
      "temperature": {
        "type": "long"
      },
      "voltage": {
        "type": "double"
      },
      "node": {
        "type": "keyword"
      },
      "voltage_corrected": {
        "type": "double",
        "on_script_error": "fail", 
        "script": {
          "source": """
        emit(doc['voltage'].value * params['multiplier'])
        """,
          "params": {
            "multiplier": 4
          }
        }
      }
    }
  }
}

Приводит к отклонению всего документа, если скрипт генерирует ошибку при индексировании. Установка значения на ignore зарегистрирует поле в поле метаданных документа _ignored и продолжит индексирование.

Массово индексируйте некоторые образцы данных с ваших датчиков в индекс my-index-000001:

resp = client.bulk(
    index="my-index-000001",
    refresh=True,
    operations=[
        {
            "index": {}
        },
        {
            "timestamp": 1516729294000,
            "temperature": 200,
            "voltage": 5.2,
            "node": "a"
        },
        {
            "index": {}
        },
        {
            "timestamp": 1516642894000,
            "temperature": 201,
            "voltage": 5.8,
            "node": "b"
        },
        {
            "index": {}
        },
        {
            "timestamp": 1516556494000,
            "temperature": 202,
            "voltage": 5.1,
            "node": "a"
        },
        {
            "index": {}
        },
        {
            "timestamp": 1516470094000,
            "temperature": 198,
            "voltage": 5.6,
            "node": "b"
        },
        {
            "index": {}
        },
        {
            "timestamp": 1516383694000,
            "temperature": 200,
            "voltage": 4.2,
            "node": "c"
        },
        {
            "index": {}
        },
        {
            "timestamp": 1516297294000,
            "temperature": 202,
            "voltage": 4,
            "node": "c"
        }
    ],
)
print(resp)
response = client.bulk(
  index: 'my-index-000001',
  refresh: true,
  body: [
    {
      index: {}
    },
    {
      timestamp: 1_516_729_294_000,
      temperature: 200,
      voltage: 5.2,
      node: 'a'
    },
    {
      index: {}
    },
    {
      timestamp: 1_516_642_894_000,
      temperature: 201,
      voltage: 5.8,
      node: 'b'
    },
    {
      index: {}
    },
    {
      timestamp: 1_516_556_494_000,
      temperature: 202,
      voltage: 5.1,
      node: 'a'
    },
    {
      index: {}
    },
    {
      timestamp: 1_516_470_094_000,
      temperature: 198,
      voltage: 5.6,
      node: 'b'
    },
    {
      index: {}
    },
    {
      timestamp: 1_516_383_694_000,
      temperature: 200,
      voltage: 4.2,
      node: 'c'
    },
    {
      index: {}
    },
    {
      timestamp: 1_516_297_294_000,
      temperature: 202,
      voltage: 4,
      node: 'c'
    }
  ]
)
puts response
const response = await client.bulk({
  index: "my-index-000001",
  refresh: "true",
  operations: [
    {
      index: {},
    },
    {
      timestamp: 1516729294000,
      temperature: 200,
      voltage: 5.2,
      node: "a",
    },
    {
      index: {},
    },
    {
      timestamp: 1516642894000,
      temperature: 201,
      voltage: 5.8,
      node: "b",
    },
    {
      index: {},
    },
    {
      timestamp: 1516556494000,
      temperature: 202,
      voltage: 5.1,
      node: "a",
    },
    {
      index: {},
    },
    {
      timestamp: 1516470094000,
      temperature: 198,
      voltage: 5.6,
      node: "b",
    },
    {
      index: {},
    },
    {
      timestamp: 1516383694000,
      temperature: 200,
      voltage: 4.2,
      node: "c",
    },
    {
      index: {},
    },
    {
      timestamp: 1516297294000,
      temperature: 202,
      voltage: 4,
      node: "c",
    },
  ],
});
console.log(response);
POST my-index-000001/_bulk?refresh=true
{ "index": {}}
{ "timestamp": 1516729294000, "temperature": 200, "voltage": 5.2, "node": "a"}
{ "index": {}}
{ "timestamp": 1516642894000, "temperature": 201, "voltage": 5.8, "node": "b"}
{ "index": {}}
{ "timestamp": 1516556494000, "temperature": 202, "voltage": 5.1, "node": "a"}
{ "index": {}}
{ "timestamp": 1516470094000, "temperature": 198, "voltage": 5.6, "node": "b"}
{ "index": {}}
{ "timestamp": 1516383694000, "temperature": 200, "voltage": 4.2, "node": "c"}
{ "index": {}}
{ "timestamp": 1516297294000, "temperature": 202, "voltage": 4.0, "node": "c"}

Теперь вы можете получить вычисленные значения в запросе поиска и найти документы на основе точных значений. Следующий запрос диапазона возвращает все документы, где вычисленное значение voltage_corrected больше или равно 16, но меньше или равно 20. Снова используйте параметр fields для API _search, чтобы получить нужные поля:

resp = client.search(
    index="my-index-000001",
    query={
        "range": {
            "voltage_corrected": {
                "gte": 16,
                "lte": 20,
                "boost": 1
            }
        }
    },
    fields=[
        "voltage_corrected",
        "node"
    ],
)
print(resp)
const response = await client.search({
  index: "my-index-000001",
  query: {
    range: {
      voltage_corrected: {
        gte: 16,
        lte: 20,
        boost: 1,
      },
    },
  },
  fields: ["voltage_corrected", "node"],
});
console.log(response);
POST my-index-000001/_search
{
  "query": {
    "range": {
      "voltage_corrected": {
        "gte": 16,
        "lte": 20,
        "boost": 1.0
      }
    }
  },
  "fields": ["voltage_corrected", "node"]
}

Ответ включает поле voltage_corrected для документов, которые соответствуют запросу диапазона, на основе вычисленного значения включённого скрипта:

{
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my-index-000001",
        "_id" : "yoSLrHgBdg9xpPrUZz_P",
        "_score" : 1.0,
        "_source" : {
          "timestamp" : 1516383694000,
          "temperature" : 200,
          "voltage" : 4.2,
          "node" : "c"
        },
        "fields" : {
          "voltage_corrected" : [
            16.8
          ],
          "node" : [
            "c"
          ]
        }
      },
      {
        "_index" : "my-index-000001",
        "_id" : "y4SLrHgBdg9xpPrUZz_P",
        "_score" : 1.0,
        "_source" : {
          "timestamp" : 1516297294000,
          "temperature" : 202,
          "voltage" : 4.0,
          "node" : "c"
        },
        "fields" : {
          "voltage_corrected" : [
            16.0
          ],
          "node" : [
            "c"
          ]
        }
      }
    ]
  }
}

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/runtime-indexed.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API