Link Search Menu Expand Document Documentation Menu

移动函数聚合

moving_fn 聚合是一种父管道聚合,它在滑动窗口上执行脚本。滑动窗口在一个从父 histogramdate histogram 聚合中提取的值序列上移动。窗口每次向右移动一个桶;每次窗口移动时,moving_fn 都会运行脚本。

使用 moving_fn 聚合来对滑动窗口内的数据进行任何数值计算。您可以使用 moving_fn 实现以下目的:

  • 趋势分析
  • 异常检测
  • 自定义时间序列分析
  • 自定义平滑算法
  • 数字信号处理 (DSP)

参数

moving_fn 聚合接受以下参数。

参数 必需/可选 数据类型 描述
buckets_path 必需 字符串 包含要处理的度量值的聚合桶路径。参阅桶路径
script(脚本) 必需 字符串或对象 计算每个数据窗口值的脚本。可以是内联脚本、存储脚本或脚本文件。脚本可以访问 buckets_path 参数中定义的变量名。
window 必需 整数 滑动窗口中的桶数量。必须是正整数。
gap_policy 可选 字符串 应用于缺失数据的策略。有效值为 skipinsert_zeros。默认值为 skip。参阅数据间隙
format 可选 字符串 一个 DecimalFormat 格式化字符串。在聚合的 value_as_string 属性中返回格式化的输出。
shift 可选 整数 窗口移动的桶数量。可以是正数(向右移动到未来桶)或负数(向左移动到过去桶)。默认值为 0,将窗口直接置于当前桶的左侧。参阅移动窗口

移动函数如何工作

moving_fn 聚合在有序桶序列的滑动窗口上操作。从父聚合的第一个桶开始,moving_fn 执行以下操作:

  1. windowshift 参数指定的桶中收集子序列(窗口)的值。
  2. 将这些值作为数组传递给 script 指定的函数。
  3. 使用 script 从数组中计算单个值。
  4. 将此值作为当前桶的结果返回。
  5. 向前移动一个桶并重复此过程。

“过去”和“未来”值指的是时间序列数据,这是移动窗口函数最常见的用例。更一般地,它们分别指的是任何有序数据序列中的前一个值和即将到来的值。

moving_fn 应用的脚本可以是预定义函数自定义脚本。桶值以 values 数组的形式提供给脚本。脚本返回一个双精度值作为结果。允许结果值为 NaN+/- Inf,但不允许 null

窗口大小

window 参数指定定义窗口大小的桶数量。

传递给 script 函数的数组是零索引的。其值在脚本中通过 values[0]values[n] 访问,其中 n = values.length - 1

移动窗口

shift 参数控制移动窗口相对于当前桶的位置。根据您的分析是否需要历史上下文、当前数据或未来预测来设置 shift。默认值为 0,这只显示过去的值(不包括当前桶)。

shift 的一些常用值如下:

shift 窗口描述  
0 仅过去的值。不包括当前值。 --[-----]x----
1 过去的值,包括当前值。 --[----x]-----
窗口/2 将窗口中心置于当前值周围。 --[--x--]-----
window 未来值,包括当前值。 --[x----]-----

当窗口在序列的开始或结束处超出可用数据时,window 会自动缩小以仅使用可用点。

[x----]--
-[x----]-
--[x----]
---[x---]
----[x--]
-----[x-]
------[x]

预定义函数

moving_fn 聚合支持许多预定义函数,这些函数可以代替自定义脚本使用。这些函数可以通过 MovingFunctions 上下文访问。例如,您可以将 max 函数作为 MovingFunctions.max(values) 访问。

下表描述了预定义函数。

功能 模型关键词 描述
最大值 max 窗口中的最大值。
最小值 min 窗口中的最小值。
总和 sum 窗口中值的总和。
非加权平均值 unweightedAvg 窗口中所有值的非加权平均值,等于 sum / window
线性加权平均 linearWeightedAvg 使用线性衰减权重进行加权平均,更加重视近期值。
指数加权移动平均 ewma 使用指数衰减权重进行加权平均,更加重视近期值。
Holt holt 使用第二个指数项来平滑长期趋势的加权平均。
Holt-Winters holt_winters 使用第三个指数项来平滑周期(季节性)效应的加权平均。
标准差 stdDev 窗口中值的总和。

所有预定义函数都将 values 数组作为它们的第一个参数。对于接受额外参数的函数,请在 values 之后按顺序传递这些参数。例如,通过将 script 值设置为 MovingFunctions.stdDev(values, MovingFunctions.unweightedAvg(values)) 来调用 stdDev 函数。

下表显示了每个模型所需的设置。

功能 额外参数 允许值 默认值 描述
max 数字数组 窗口的最大值。
min 数字数组 窗口的最小值。
sum 数字数组 窗口中所有值的总和。
unweightedAvg 数字数组 窗口中所有值的算术平均值。
linearWeightedAvg 数字数组 窗口中所有值的加权平均值,其中近期值权重更高。
ewma alpha [0, 1] 0.3 衰减参数。值越高,近期数据点的权重越大。
holt alpha [0, 1] 0.3 水平分量的衰减参数。
  beta [0, 1] 0.1 趋势分量的衰减参数。
holt_winters alpha [0, 1] 0.3 水平分量的衰减参数。
  beta [0, 1] 0.3 趋势分量的衰减参数。
  gamma [0, 1] 0.3 季节性分量的衰减参数。
  type add, mult add 定义季节性如何建模:加法或乘法。
  period 整数 1 构成周期的桶数量。
  pad 布尔型 true 是否为 mult 类型模型中的 0 值添加一个小偏移量,以避免除以零错误。
stdDev avg 任意双精度值 窗口的标准差。要计算有意义的标准差,请使用滑动窗口数组的均值,通常是 MovingFunctions.unweightedAvg(values)

预定义函数不支持缺少参数的函数签名。因此,您必须提供额外参数,即使使用默认值也是如此。

示例:预定义函数

以下示例使用 OpenSearch Dashboards 日志样本数据创建了一个以一周为间隔的日期直方图。sum 子聚合计算每周记录的所有字节的总和。最后,moving_fn 聚合计算字节总和的标准差,使用 5window 大小、默认 0shift 和非加权平均值。

POST /opensearch_dashboards_sample_data_logs/_search
{
  "size": 0,
  "aggs": {
    "my_date_histo": {
      "date_histogram": {
        "field": "timestamp",
        "calendar_interval": "week"
      },
      "aggs": {
        "the_sum": {
          "sum": { "field": "bytes" }
        },
        "the_movavg": {
          "moving_fn": {
            "buckets_path": "the_sum",
            "window": 5,
            "script": "MovingFunctions.stdDev(values, MovingFunctions.unweightedAvg(values))"
          }
        }
      }
    }
  }
}

示例响应

响应显示从第二个桶中的零值开始的移动窗口的标准差。stdDev 函数对于空窗口或仅包含无效值(nullNaN)的窗口返回 0

响应
{
  "took": 15,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 10000,
      "relation": "gte"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "my_date_histo": {
      "buckets": [
        {
          "key_as_string": "2025-03-24T00:00:00.000Z",
          "key": 1742774400000,
          "doc_count": 249,
          "the_sum": {
            "value": 1531493
          },
          "the_movavg": {
            "value": null
          }
        },
        {
          "key_as_string": "2025-03-31T00:00:00.000Z",
          "key": 1743379200000,
          "doc_count": 1617,
          "the_sum": {
            "value": 9213161
          },
          "the_movavg": {
            "value": 0
          }
        },
        {
          "key_as_string": "2025-04-07T00:00:00.000Z",
          "key": 1743984000000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9188671
          },
          "the_movavg": {
            "value": 3840834
          }
        },
        {
          "key_as_string": "2025-04-14T00:00:00.000Z",
          "key": 1744588800000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9244851
          },
          "the_movavg": {
            "value": 3615414.498228507
          }
        },
        {
          "key_as_string": "2025-04-21T00:00:00.000Z",
          "key": 1745193600000,
          "doc_count": 1609,
          "the_sum": {
            "value": 9061045
          },
          "the_movavg": {
            "value": 3327358.65618917
          }
        },
        {
          "key_as_string": "2025-04-28T00:00:00.000Z",
          "key": 1745798400000,
          "doc_count": 1554,
          "the_sum": {
            "value": 8713507
          },
          "the_movavg": {
            "value": 3058812.9440705855
          }
        },
        {
          "key_as_string": "2025-05-05T00:00:00.000Z",
          "key": 1746403200000,
          "doc_count": 1710,
          "the_sum": {
            "value": 9544718
          },
          "the_movavg": {
            "value": 195603.33146038183
          }
        },
        {
          "key_as_string": "2025-05-12T00:00:00.000Z",
          "key": 1747008000000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9155820
          },
          "the_movavg": {
            "value": 270085.92336040025
          }
        },
        {
          "key_as_string": "2025-05-19T00:00:00.000Z",
          "key": 1747612800000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9025078
          },
          "the_movavg": {
            "value": 269477.75659701484
          }
        },
        {
          "key_as_string": "2025-05-26T00:00:00.000Z",
          "key": 1748217600000,
          "doc_count": 895,
          "the_sum": {
            "value": 5047345
          },
          "the_movavg": {
            "value": 267356.5422566652
          }
        }
      ]
    }
  }
}

自定义脚本

您可以提供任意自定义脚本来计算 moving_fn 结果。自定义脚本使用 Painless 脚本语言。

示例:自定义脚本

以下示例使用 OpenSearch Dashboards 电子商务样本数据创建了一个以一周为间隔的日期直方图。sum 子聚合计算每周所有应税收入的总和。然后,moving_fn 脚本返回当前值前两个值中的较大者,如果这两个值不可用则返回 NaN

POST /opensearch_dashboards_sample_data_ecommerce/_search
{
  "size": 0,
  "aggs": {
    "my_date_histo": {
      "date_histogram": {
        "field": "order_date",
        "calendar_interval": "week"
      },
      "aggs": {
        "the_sum": {
          "sum": { "field": "taxful_total_price" }
        },
        "the_movavg": {
          "moving_fn": {
            "buckets_path": "the_sum",
            "window": 2,
            "script": "return (values.length < 2 ? Double.NaN : (values[0]>values[1] ? values[0] : values[1]))"
          }
        }
      }
    }
  }
}

示例返回从第三个桶开始的计算结果,该桶有足够的先前数据来执行计算。

响应
{
  "took": 7,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 4675,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "my_date_histo": {
      "buckets": [
        {
          "key_as_string": "2025-03-24T00:00:00.000Z",
          "key": 1742774400000,
          "doc_count": 582,
          "the_sum": {
            "value": 41455.5390625
          },
          "the_movavg": {
            "value": null
          }
        },
        {
          "key_as_string": "2025-03-31T00:00:00.000Z",
          "key": 1743379200000,
          "doc_count": 1048,
          "the_sum": {
            "value": 79448.60546875
          },
          "the_movavg": {
            "value": null
          }
        },
        {
          "key_as_string": "2025-04-07T00:00:00.000Z",
          "key": 1743984000000,
          "doc_count": 1048,
          "the_sum": {
            "value": 78208.4296875
          },
          "the_movavg": {
            "value": 79448.60546875
          }
        },
        {
          "key_as_string": "2025-04-14T00:00:00.000Z",
          "key": 1744588800000,
          "doc_count": 1073,
          "the_sum": {
            "value": 81277.296875
          },
          "the_movavg": {
            "value": 79448.60546875
          }
        },
        {
          "key_as_string": "2025-04-21T00:00:00.000Z",
          "key": 1745193600000,
          "doc_count": 924,
          "the_sum": {
            "value": 70494.2578125
          },
          "the_movavg": {
            "value": 81277.296875
          }
        }
      ]
    }
  }
}

示例:移动平均

moving_fn 聚合取代了已弃用的 moving_avg 聚合。moving_fn 聚合类似于 moving_avg 聚合,但功能更强大,因为它计算任意函数而不仅仅是平均值。所有预定义的 moving_avg 函数也都在 moving_fn 中实现。

holt 模型是一种移动平均,它使用由 alphabeta 参数控制的指数衰减权重。以下示例使用 OpenSearch Dashboards 日志样本数据创建了一个以一周为间隔的日期直方图。sum 子聚合计算每周所有字节的总和。最后,moving_fn 聚合使用 Holt 模型计算字节总和的加权平均值,其中 window 大小为 6,默认 shift0alpha 值为 0.3beta 值为 0.1

POST /opensearch_dashboards_sample_data_logs/_search
{
  "size": 0,
  "aggs": {
    "my_date_histogram": {
      "date_histogram": {
        "field": "timestamp",
        "calendar_interval": "week"
      },
      "aggs": {
        "the_sum": {
          "sum": { "field": "bytes" }
        },
        "the_movavg": {
          "moving_fn": {
            "buckets_path": "the_sum",
            "window": 6,
            "script": "MovingFunctions.holt(values, 0.3, 0.1)"
          }
        }
      }
    }
  }
}

聚合返回从第二个桶开始的移动 holt 平均值。

响应
{
  "took": 16,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 10000,
      "relation": "gte"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "my_date_histogram": {
      "buckets": [
        {
          "key_as_string": "2025-03-24T00:00:00.000Z",
          "key": 1742774400000,
          "doc_count": 249,
          "the_sum": {
            "value": 1531493
          },
          "the_movavg": {
            "value": null
          }
        },
        {
          "key_as_string": "2025-03-31T00:00:00.000Z",
          "key": 1743379200000,
          "doc_count": 1617,
          "the_sum": {
            "value": 9213161
          },
          "the_movavg": {
            "value": 1531493
          }
        },
        {
          "key_as_string": "2025-04-07T00:00:00.000Z",
          "key": 1743984000000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9188671
          },
          "the_movavg": {
            "value": 3835993.3999999994
          }
        },
        {
          "key_as_string": "2025-04-14T00:00:00.000Z",
          "key": 1744588800000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9244851
          },
          "the_movavg": {
            "value": 5603111.707999999
          }
        },
        {
          "key_as_string": "2025-04-21T00:00:00.000Z",
          "key": 1745193600000,
          "doc_count": 1609,
          "the_sum": {
            "value": 9061045
          },
          "the_movavg": {
            "value": 6964515.302359998
          }
        },
        {
          "key_as_string": "2025-04-28T00:00:00.000Z",
          "key": 1745798400000,
          "doc_count": 1554,
          "the_sum": {
            "value": 8713507
          },
          "the_movavg": {
            "value": 7930766.089341199
          }
        },
        {
          "key_as_string": "2025-05-05T00:00:00.000Z",
          "key": 1746403200000,
          "doc_count": 1710,
          "the_sum": {
            "value": 9544718
          },
          "the_movavg": {
            "value": 8536788.607547803
          }
        },
        {
          "key_as_string": "2025-05-12T00:00:00.000Z",
          "key": 1747008000000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9155820
          },
          "the_movavg": {
            "value": 9172269.837272028
          }
        },
        {
          "key_as_string": "2025-05-19T00:00:00.000Z",
          "key": 1747612800000,
          "doc_count": 1610,
          "the_sum": {
            "value": 9025078
          },
          "the_movavg": {
            "value": 9166173.88436614
          }
        },
        {
          "key_as_string": "2025-05-26T00:00:00.000Z",
          "key": 1748217600000,
          "doc_count": 895,
          "the_sum": {
            "value": 5047345
          },
          "the_movavg": {
            "value": 9123157.830417283
          }
        }
      ]
    }
  }
}