Aggregate metric field type

edit

Stores pre-aggregated numeric values for metric aggregations. An aggregate_metric_double field is an object containing one or more of the following metric sub-fields: min, max, sum, and value_count.

When you run certain metric aggregations on an aggregate_metric_double field, the aggregation uses the related sub-field’s values. For example, a min aggregation on an aggregate_metric_double field returns the minimum value of all min sub-fields.

An aggregate_metric_double field stores a single numeric doc value for each metric sub-field. Array values are not supported. min, max, and sum values are double numbers. value_count is a positive long number.

resp = client.indices.create(
    index="my-index",
    mappings={
        "properties": {
            "my-agg-metric-field": {
                "type": "aggregate_metric_double",
                "metrics": [
                    "min",
                    "max",
                    "sum",
                    "value_count"
                ],
                "default_metric": "max"
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my-index',
  body: {
    mappings: {
      properties: {
        "my-agg-metric-field": {
          type: 'aggregate_metric_double',
          metrics: [
            'min',
            'max',
            'sum',
            'value_count'
          ],
          default_metric: 'max'
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "my-index",
  mappings: {
    properties: {
      "my-agg-metric-field": {
        type: "aggregate_metric_double",
        metrics: ["min", "max", "sum", "value_count"],
        default_metric: "max",
      },
    },
  },
});
console.log(response);
PUT my-index
{
  "mappings": {
    "properties": {
      "my-agg-metric-field": {
        "type": "aggregate_metric_double",
        "metrics": [ "min", "max", "sum", "value_count" ],
        "default_metric": "max"
      }
    }
  }
}

Parameters for aggregate_metric_double fields

edit
metrics
(Required, array of strings) Array of metric sub-fields to store. Each value corresponds to a metric aggregation. Valid values are min, max, sum, and value_count. You must specify at least one value.
default_metric
(Required, string) Default metric sub-field to use for queries, scripts, and aggregations that don’t use a sub-field. Must be a value from the metrics array.
time_series_metric

(Optional, string) Marks the field as a time series metric. The value is the metric type. You can’t update this parameter for existing fields.

Valid time_series_metric values for aggregate_metric_double fields
gauge
A metric that represents a single numeric that can arbitrarily increase or decrease. For example, a temperature or available disk space.
null (Default)
Not a time series metric.

Uses

edit

We designed aggregate_metric_double fields for use with the following aggregations:

  • A min aggregation returns the minimum value of all min sub-fields.
  • A max aggregation returns the maximum value of all max sub-fields.
  • A sum aggregation returns the sum of the values of all sum sub-fields.
  • A value_count aggregation returns the sum of the values of all value_count sub-fields.
  • A avg aggregation. There is no avg sub-field; the result of the avg aggregation is computed using the sum and value_count metrics. To run an avg aggregation, the field must contain both sum and value_count metric sub-field.

Running any other aggregation on an aggregate_metric_double field will fail with an "unsupported aggregation" error.

Finally, an aggregate_metric_double field supports the following queries for which it behaves as a double by delegating its behavior to its default_metric sub-field:

Examples

edit

The following create index API request creates an index with an aggregate_metric_double field named agg_metric. The request sets max as the field’s default_metric.

resp = client.indices.create(
    index="stats-index",
    mappings={
        "properties": {
            "agg_metric": {
                "type": "aggregate_metric_double",
                "metrics": [
                    "min",
                    "max",
                    "sum",
                    "value_count"
                ],
                "default_metric": "max"
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'stats-index',
  body: {
    mappings: {
      properties: {
        agg_metric: {
          type: 'aggregate_metric_double',
          metrics: [
            'min',
            'max',
            'sum',
            'value_count'
          ],
          default_metric: 'max'
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "stats-index",
  mappings: {
    properties: {
      agg_metric: {
        type: "aggregate_metric_double",
        metrics: ["min", "max", "sum", "value_count"],
        default_metric: "max",
      },
    },
  },
});
console.log(response);
PUT stats-index
{
  "mappings": {
    "properties": {
      "agg_metric": {
        "type": "aggregate_metric_double",
        "metrics": [ "min", "max", "sum", "value_count" ],
        "default_metric": "max"
      }
    }
  }
}

The following index API request adds documents with pre-aggregated data in the agg_metric field.

resp = client.index(
    index="stats-index",
    id="1",
    document={
        "agg_metric": {
            "min": -302.5,
            "max": 702.3,
            "sum": 200,
            "value_count": 25
        }
    },
)
print(resp)

resp1 = client.index(
    index="stats-index",
    id="2",
    document={
        "agg_metric": {
            "min": -93,
            "max": 1702.3,
            "sum": 300,
            "value_count": 25
        }
    },
)
print(resp1)
response = client.index(
  index: 'stats-index',
  id: 1,
  body: {
    agg_metric: {
      min: -302.5,
      max: 702.3,
      sum: 200,
      value_count: 25
    }
  }
)
puts response

response = client.index(
  index: 'stats-index',
  id: 2,
  body: {
    agg_metric: {
      min: -93,
      max: 1702.3,
      sum: 300,
      value_count: 25
    }
  }
)
puts response
const response = await client.index({
  index: "stats-index",
  id: 1,
  document: {
    agg_metric: {
      min: -302.5,
      max: 702.3,
      sum: 200,
      value_count: 25,
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "stats-index",
  id: 2,
  document: {
    agg_metric: {
      min: -93,
      max: 1702.3,
      sum: 300,
      value_count: 25,
    },
  },
});
console.log(response1);
PUT stats-index/_doc/1
{
  "agg_metric": {
    "min": -302.50,
    "max": 702.30,
    "sum": 200.0,
    "value_count": 25
  }
}

PUT stats-index/_doc/2
{
  "agg_metric": {
    "min": -93.00,
    "max": 1702.30,
    "sum": 300.00,
    "value_count": 25
  }
}

You can run min, max, sum, value_count, and avg aggregations on a agg_metric field.

resp = client.search(
    index="stats-index",
    size="0",
    aggs={
        "metric_min": {
            "min": {
                "field": "agg_metric"
            }
        },
        "metric_max": {
            "max": {
                "field": "agg_metric"
            }
        },
        "metric_value_count": {
            "value_count": {
                "field": "agg_metric"
            }
        },
        "metric_sum": {
            "sum": {
                "field": "agg_metric"
            }
        },
        "metric_avg": {
            "avg": {
                "field": "agg_metric"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'stats-index',
  size: 0,
  body: {
    aggregations: {
      metric_min: {
        min: {
          field: 'agg_metric'
        }
      },
      metric_max: {
        max: {
          field: 'agg_metric'
        }
      },
      metric_value_count: {
        value_count: {
          field: 'agg_metric'
        }
      },
      metric_sum: {
        sum: {
          field: 'agg_metric'
        }
      },
      metric_avg: {
        avg: {
          field: 'agg_metric'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "stats-index",
  size: 0,
  aggs: {
    metric_min: {
      min: {
        field: "agg_metric",
      },
    },
    metric_max: {
      max: {
        field: "agg_metric",
      },
    },
    metric_value_count: {
      value_count: {
        field: "agg_metric",
      },
    },
    metric_sum: {
      sum: {
        field: "agg_metric",
      },
    },
    metric_avg: {
      avg: {
        field: "agg_metric",
      },
    },
  },
});
console.log(response);
POST stats-index/_search?size=0
{
  "aggs": {
    "metric_min": { "min": { "field": "agg_metric" } },
    "metric_max": { "max": { "field": "agg_metric" } },
    "metric_value_count": { "value_count": { "field": "agg_metric" } },
    "metric_sum": { "sum": { "field": "agg_metric" } },
    "metric_avg": { "avg": { "field": "agg_metric" } }
  }
}

The aggregation results are based on related metric sub-field values.

{
...
  "aggregations": {
    "metric_min": {
      "value": -302.5
    },
    "metric_max": {
      "value": 1702.3
    },
    "metric_value_count": {
      "value": 50
    },
    "metric_sum": {
      "value": 500.0
    },
    "metric_avg": {
      "value": 10.0
    }
  }
}

Queries on a aggregate_metric_double field use the default_metric value.

resp = client.search(
    index="stats-index",
    query={
        "term": {
            "agg_metric": {
                "value": 702.3
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'stats-index',
  body: {
    query: {
      term: {
        agg_metric: {
          value: 702.3
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "stats-index",
  query: {
    term: {
      agg_metric: {
        value: 702.3,
      },
    },
  },
});
console.log(response);
GET stats-index/_search
{
  "query": {
    "term": {
      "agg_metric": {
        "value": 702.30
      }
    }
  }
}

The search returns the following hit. The value of the default_metric field, max, matches the query value.

{
  ...
    "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1.0,
    "hits": [
      {
        "_index": "stats-index",
        "_id": "1",
        "_score": 1.0,
        "_source": {
          "agg_metric": {
            "min": -302.5,
            "max": 702.3,
            "sum": 200.0,
            "value_count": 25
          }
        }
      }
    ]
  }
}

Synthetic _source

edit

Synthetic _source is Generally Available only for TSDB indices (indices that have index.mode set to time_series). For other indices synthetic _source is in technical preview. Features in technical preview may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.

aggregate_metric-double fields support synthetic _source in their default configuration.

For example:

resp = client.indices.create(
    index="idx",
    mappings={
        "_source": {
            "mode": "synthetic"
        },
        "properties": {
            "agg_metric": {
                "type": "aggregate_metric_double",
                "metrics": [
                    "min",
                    "max",
                    "sum",
                    "value_count"
                ],
                "default_metric": "max"
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="idx",
    id="1",
    document={
        "agg_metric": {
            "min": -302.5,
            "max": 702.3,
            "sum": 200,
            "value_count": 25
        }
    },
)
print(resp1)
response = client.indices.create(
  index: 'idx',
  body: {
    mappings: {
      _source: {
        mode: 'synthetic'
      },
      properties: {
        agg_metric: {
          type: 'aggregate_metric_double',
          metrics: [
            'min',
            'max',
            'sum',
            'value_count'
          ],
          default_metric: 'max'
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'idx',
  id: 1,
  body: {
    agg_metric: {
      min: -302.5,
      max: 702.3,
      sum: 200,
      value_count: 25
    }
  }
)
puts response
const response = await client.indices.create({
  index: "idx",
  mappings: {
    _source: {
      mode: "synthetic",
    },
    properties: {
      agg_metric: {
        type: "aggregate_metric_double",
        metrics: ["min", "max", "sum", "value_count"],
        default_metric: "max",
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "idx",
  id: 1,
  document: {
    agg_metric: {
      min: -302.5,
      max: 702.3,
      sum: 200,
      value_count: 25,
    },
  },
});
console.log(response1);
PUT idx
{
  "mappings": {
    "_source": { "mode": "synthetic" },
    "properties": {
      "agg_metric": {
        "type": "aggregate_metric_double",
        "metrics": [ "min", "max", "sum", "value_count" ],
        "default_metric": "max"
      }
    }
  }
}

PUT idx/_doc/1
{
  "agg_metric": {
    "min": -302.50,
    "max": 702.30,
    "sum": 200.0,
    "value_count": 25
  }
}

Will become:

{
  "agg_metric": {
    "min": -302.50,
    "max": 702.30,
    "sum": 200.0,
    "value_count": 25
  }
}