Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Guide [8.17] ›Агрегации ›Агрегации метрик

Агрегация Sum

Агрегация метрик single-value, которая суммирует числовые значения, извлеченные из агрегированных документов. Эти значения могут быть извлечены либо из определенных числовых, либо из гистограммных полей.

Предположим, данные состоят из документов, представляющих записи о продажах. Мы можем суммировать цену продажи всех шляп с помощью:

resp = client.search(
    index="sales",
    size="0",
    query={
        "constant_score": {
            "filter": {
                "match": {
                    "type": "hat"
                }
            }
        }
    },
    aggs={
        "hat_prices": {
            "sum": {
                "field": "price"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'sales',
  size: 0,
  body: {
    query: {
      constant_score: {
        filter: {
          match: {
            type: 'hat'
          }
        }
      }
    },
    aggregations: {
      hat_prices: {
        sum: {
          field: 'price'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "sales",
  size: 0,
  query: {
    constant_score: {
      filter: {
        match: {
          type: "hat",
        },
      },
    },
  },
  aggs: {
    hat_prices: {
      sum: {
        field: "price",
      },
    },
  },
});
console.log(response);
POST /sales/_search?size=0
{
  "query": {
    "constant_score": {
      "filter": {
        "match": { "type": "hat" }
      }
    }
  },
  "aggs": {
    "hat_prices": { "sum": { "field": "price" } }
  }
}

Получая в результате:

{
  ...
  "aggregations": {
    "hat_prices": {
      "value": 450.0
    }
  }
}

Имя агрегации (hat_prices выше) также служит ключом, по которому можно получить результат агрегации из возвращенного ответа.

Скрипт

Если вам нужно получить sum для чего-то более сложного, чем одно поле, выполните агрегацию по полю runtime.

resp = client.search(
    index="sales",
    size="0",
    runtime_mappings={
        "price.weighted": {
            "type": "double",
            "script": "\n        double price = doc['price'].value;\n        if (doc['promoted'].value) {\n          price *= 0.8;\n        }\n        emit(price);\n      "
        }
    },
    query={
        "constant_score": {
            "filter": {
                "match": {
                    "type": "hat"
                }
            }
        }
    },
    aggs={
        "hat_prices": {
            "sum": {
                "field": "price.weighted"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'sales',
  size: 0,
  body: {
    runtime_mappings: {
      'price.weighted' => {
        type: 'double',
        script: "\n        double price = doc['price'].value;\n        if (doc['promoted'].value) {\n          price *= 0.8;\n        }\n        emit(price);\n      "
      }
    },
    query: {
      constant_score: {
        filter: {
          match: {
            type: 'hat'
          }
        }
      }
    },
    aggregations: {
      hat_prices: {
        sum: {
          field: 'price.weighted'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "sales",
  size: 0,
  runtime_mappings: {
    "price.weighted": {
      type: "double",
      script:
        "\n        double price = doc['price'].value;\n        if (doc['promoted'].value) {\n          price *= 0.8;\n        }\n        emit(price);\n      ",
    },
  },
  query: {
    constant_score: {
      filter: {
        match: {
          type: "hat",
        },
      },
    },
  },
  aggs: {
    hat_prices: {
      sum: {
        field: "price.weighted",
      },
    },
  },
});
console.log(response);
POST /sales/_search?size=0
{
  "runtime_mappings": {
    "price.weighted": {
      "type": "double",
      "script": """
        double price = doc['price'].value;
        if (doc['promoted'].value) {
          price *= 0.8;
        }
        emit(price);
      """
    }
  },
  "query": {
    "constant_score": {
      "filter": {
        "match": { "type": "hat" }
      }
    }
  },
  "aggs": {
    "hat_prices": {
      "sum": {
        "field": "price.weighted"
      }
    }
  }
}

Отсутствующее значение

Параметр missing определяет, как должны обрабатываться документы, у которых отсутствует значение. По умолчанию, документы с отсутствующим значением игнорируются, но также можно обработать их так, как будто у них есть значение. Например, это рассматривает все продажи шляп без цены как 100.

resp = client.search(
    index="sales",
    size="0",
    query={
        "constant_score": {
            "filter": {
                "match": {
                    "type": "hat"
                }
            }
        }
    },
    aggs={
        "hat_prices": {
            "sum": {
                "field": "price",
                "missing": 100
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'sales',
  size: 0,
  body: {
    query: {
      constant_score: {
        filter: {
          match: {
            type: 'hat'
          }
        }
      }
    },
    aggregations: {
      hat_prices: {
        sum: {
          field: 'price',
          missing: 100
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "sales",
  size: 0,
  query: {
    constant_score: {
      filter: {
        match: {
          type: "hat",
        },
      },
    },
  },
  aggs: {
    hat_prices: {
      sum: {
        field: "price",
        missing: 100,
      },
    },
  },
});
console.log(response);
POST /sales/_search?size=0
{
  "query": {
    "constant_score": {
      "filter": {
        "match": { "type": "hat" }
      }
    }
  },
  "aggs": {
    "hat_prices": {
      "sum": {
        "field": "price",
        "missing": 100 
      }
    }
  }
}

Гистограммные поля

Когда sum вычисляется по гистограммным полям, результатом агрегации является сумма всех элементов в массиве values, умноженная на число в том же положении в массиве counts.

Например, для следующего индекса, который хранит предварительно агрегированные гистограммы с метриками задержки для различных сетей:

resp = client.indices.create(
    index="metrics_index",
    mappings={
        "properties": {
            "latency_histo": {
                "type": "histogram"
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="metrics_index",
    id="1",
    refresh=True,
    document={
        "network.name": "net-1",
        "latency_histo": {
            "values": [
                0.1,
                0.2,
                0.3,
                0.4,
                0.5
            ],
            "counts": [
                3,
                7,
                23,
                12,
                6
            ]
        }
    },
)
print(resp1)

resp2 = client.index(
    index="metrics_index",
    id="2",
    refresh=True,
    document={
        "network.name": "net-2",
        "latency_histo": {
            "values": [
                0.1,
                0.2,
                0.3,
                0.4,
                0.5
            ],
            "counts": [
                8,
                17,
                8,
                7,
                6
            ]
        }
    },
)
print(resp2)

resp3 = client.search(
    index="metrics_index",
    size="0",
    filter_path="aggregations",
    aggs={
        "total_latency": {
            "sum": {
                "field": "latency_histo"
            }
        }
    },
)
print(resp3)
response = client.indices.create(
  index: 'metrics_index',
  body: {
    mappings: {
      properties: {
        latency_histo: {
          type: 'histogram'
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'metrics_index',
  id: 1,
  refresh: true,
  body: {
    'network.name' => 'net-1',
    latency_histo: {
      values: [
        0.1,
        0.2,
        0.3,
        0.4,
        0.5
      ],
      counts: [
        3,
        7,
        23,
        12,
        6
      ]
    }
  }
)
puts response

response = client.index(
  index: 'metrics_index',
  id: 2,
  refresh: true,
  body: {
    'network.name' => 'net-2',
    latency_histo: {
      values: [
        0.1,
        0.2,
        0.3,
        0.4,
        0.5
      ],
      counts: [
        8,
        17,
        8,
        7,
        6
      ]
    }
  }
)
puts response

response = client.search(
  index: 'metrics_index',
  size: 0,
  filter_path: 'aggregations',
  body: {
    aggregations: {
      total_latency: {
        sum: {
          field: 'latency_histo'
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "metrics_index",
  mappings: {
    properties: {
      latency_histo: {
        type: "histogram",
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "metrics_index",
  id: 1,
  refresh: "true",
  document: {
    "network.name": "net-1",
    latency_histo: {
      values: [0.1, 0.2, 0.3, 0.4, 0.5],
      counts: [3, 7, 23, 12, 6],
    },
  },
});
console.log(response1);

const response2 = await client.index({
  index: "metrics_index",
  id: 2,
  refresh: "true",
  document: {
    "network.name": "net-2",
    latency_histo: {
      values: [0.1, 0.2, 0.3, 0.4, 0.5],
      counts: [8, 17, 8, 7, 6],
    },
  },
});
console.log(response2);

const response3 = await client.search({
  index: "metrics_index",
  size: 0,
  filter_path: "aggregations",
  aggs: {
    total_latency: {
      sum: {
        field: "latency_histo",
      },
    },
  },
});
console.log(response3);
PUT metrics_index
{
  "mappings": {
    "properties": {
      "latency_histo": { "type": "histogram" }
    }
  }
}

PUT metrics_index/_doc/1?refresh
{
  "network.name" : "net-1",
  "latency_histo" : {
      "values" : [0.1, 0.2, 0.3, 0.4, 0.5],
      "counts" : [3, 7, 23, 12, 6]
   }
}

PUT metrics_index/_doc/2?refresh
{
  "network.name" : "net-2",
  "latency_histo" : {
      "values" :  [0.1, 0.2, 0.3, 0.4, 0.5],
      "counts" : [8, 17, 8, 7, 6]
   }
}

POST /metrics_index/_search?size=0&filter_path=aggregations
{
  "aggs" : {
    "total_latency" : { "sum" : { "field" : "latency_histo" } }
  }
}

Для каждого гистограммного поля, агрегация sum добавит каждое число в массиве values, умноженное на соответствующее значение счетчика в массиве counts.

В конечном итоге, она добавит все значения для всех гистограмм и вернет следующий результат:

{
  "aggregations": {
    "total_latency": {
      "value": 28.8
    }
  }
}

© 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/search-aggregations-metrics-sum-aggregation.html

Spec-Zone.ru

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