[comment]: # ({e1a912b1-6537e63f})
# Foreach 函数

[comment]: # ({/e1a912b1-6537e63f})

[comment]: # ({d194b7c7-7d50e3a2})
### 概述

foreach 函数用于 [聚合计算](/manual/config/items/itemtypes/calculated#data-aggregations)，根据所使用的 **监控项过滤器** 为每个被选中的监控项返回一个聚合值。返回的是一个值数组。

例如，`avg_foreach` 函数会返回一个值数组，其中每个值都是在指定时间间隔内所选监控项的 *平均* 历史值。

::: noteimportant
foreach 函数仅支持在 [计算型监控项](/manual/config/items/itemtypes/calculated) 公式中使用。
它们不能在普通监控项键值中调用，也不能直接用于构建触发器表达式。
在触发器表达式中，可以通过引用其键值来使用计算型监控项。
:::

[item filter](#item-filter-syntax) 是 foreach 函数语法的一部分。
监控项过滤器支持使用通配符，因此可以非常灵活地选择所需的监控项。

[comment]: # ({/d194b7c7-7d50e3a2})

[comment]: # ({2afbf13f-c9e1960d})
### 支持的函数

|Function|Description|
|--|--------|
|*avg_foreach*|返回每个监控项的平均值。|
|*bucket_rate_foreach*|返回成对的值（bucket 上限，速率值），适用于 [`histogram_quantile()`](/manual/config/triggers/expression/aggregate#histogram-quantile) 函数，其中“bucket 上限”是由 <parameter number> [参数](#additional-parameters) 定义的监控项 key 参数的值。|
|*count_foreach*|返回每个监控项的值数量。|
|*exists_foreach*|为每个已启用的监控项返回 '1'。|
|*last_foreach*|返回每个监控项的最后一个值。|
|*max_foreach*|返回每个监控项的最大值。|
|*min_foreach*|返回每个监控项的最小值。|
|*sum_foreach*|返回每个监控项的值总和。|

[comment]: # ({/2afbf13f-c9e1960d})

[comment]: # ({a8e9955e-2cf639a9})
### 函数语法

Foreach 函数支持两个通用参数：`监控项过滤器`（详见下文）和 `时间周期`：

    foreach_function(item filter,time period)

例如： 

`avg_foreach(/*/mysql.qps?[group="MySQL Servers"],5m)`

将返回 MySQL 服务器组中每个“mysql.qps”监控项的五分钟平均值。

请注意，某些函数还支持额外的[参数](#additional-parameters)。

[comment]: # ({/a8e9955e-2cf639a9})

[comment]: # ({f8b1fa52-737d2e38})
#### 监控项过滤器语法

监控项过滤器：

    /host/key[parameters]?[conditions]

由四个部分组成，其中：

*   host - 主机名称
*   key - 监控项键值（不含参数）
*   parameters - 监控项键值参数
*   conditions - 基于主机组和/或监控项标签的条件（以表达式形式）

仅允许在 conditions 表达式内部使用空格。

**通配符用法**

*   可使用通配符替代主机名称、监控项键值或单个监控项键值参数。
*   host 或 key 中必须有一项是不使用通配符明确指定的。因此，`/host/*` 和 `/*/key` 是有效过滤器，而 `/*/*` 无效。
*   通配符不能用于主机名称、监控项键值或监控项键值参数的*一部分*。
*   通配符不能匹配多个监控项键值参数。因此，必须分别为每个参数单独指定通配符（即 `key[abc,*,*]`）。

**条件表达式**

conditions 表达式支持：

*   操作数：
    *   group - 主机组
    *   tag - 监控项标签
    *   `"<text>"` - 字符串常量，使用转义字符 `\` 对 `"` 和 `\` 进行转义
*   区分大小写的字符串比较运算符：`=`, `<>`
*   逻辑运算符：`and`, `or`, `not`
*   使用括号分组：`(` `)`

字符串常量必须使用引号。仅支持区分大小写的完整字符串比较。

:::notewarning
在过滤器中指定标签时（即 `tag="tagname:value"`），冒号 ":" 用作分隔符。  
其后的所有内容都会被视为标签值。因此，目前不支持指定名称中包含 ":" 的标签。
:::

**示例**

可使用复杂过滤器来引用监控项键值、主机组和标签，如下例所示：

|Syntax example|Description|
|--|--|
|`/host/key[abc,*]`|匹配此主机上的类似监控项。|
|`/*/key`|匹配任意主机上的相同监控项。|
|`/*/key?[group="ABC" and tag="tagname:value"]`|匹配 ABC 组中任意主机上带有 'tagname:value' 标签的相同监控项。|
|`/*/key[a,*,c]?[(group="ABC" and tag="Tag1") or (group="DEF" and (tag="Tag2" or tag="Tag3:value"))]`|匹配 ABC 或 DEF 组中任意主机上带有相应标签的类似监控项。|

所有被引用的监控项都必须存在并采集数据。  
只有已启用主机上的已启用监控项才会被纳入计算。  
处于不支持状态的监控项不会被纳入。

::: noteimportant
如果被引用监控项的键值发生更改，则必须手动更新过滤器。
:::

指定父主机组时，将包含该父组及其所有嵌套主机组中的监控项。

[comment]: # ({/f8b1fa52-737d2e38})

[comment]: # ({2ab7aef7-0a9b9b28})
#### 时间周期

**第二个**参数用于指定聚合的时间周期。
时间周期只能以时间形式表示，不支持值的数量（以 **\#** 为前缀）。

为方便起见，此参数中可以使用[支持的单位符号](/manual/appendix/suffixes)，
例如，使用“5m”（五分钟）代替“300s”（300 秒），或使用“1d”（一天）代替“86400”（86400 秒）。

对于 *last\_foreach* 函数，时间周期是一个可选参数（自 Zabbix 7.0 起支持），可以省略：

    last_foreach(/*/key?[group="host group"])

*time period* 不支持与 *exists\_foreach* 函数一起使用。

[comment]: # ({/2ab7aef7-0a9b9b28})

[comment]: # ({a4d91525-bf880e22})
#### 附加参数

**bucket\_rate\_foreach**

*bucket\_rate\_foreach* 函数支持第三个可选参数：

    bucket_rate_foreach(item filter,time period,<parameter number>)

其中，<parameter number> 是监控项键中“bucket”值的位置。
例如，如果 myItem\[aaa,0.2\] 中的“bucket”值是“0.2”，那么它的位置就是 2。

<parameter number> 的默认值为“1”。

**count\_foreach**

*count\_foreach* 函数支持第三和第四个可选参数：

    count_foreach(item filter,time period,<operator>,<pattern>)

其中：

-   **operator** 是用于监控项值的条件运算符（必须用双引号括起来）。支持的 `operators`：<br>*eq* - 等于<br>*ne* - 不等于<br>*gt* - 大于<br>*ge* - 大于或等于<br>*lt* - 小于<br>*le* - 小于或等于<br>*like* - 包含模式时匹配（区分大小写）<br>*bitand* - 按位与<br>*regexp* - 与 `pattern` 中给定的正则表达式进行区分大小写匹配<br>*iregexp* - 与 `pattern` 中给定的正则表达式进行不区分大小写匹配<br>
-   **pattern** 是必需的模式（字符串参数必须用双引号括起来）；如果第三个参数中指定了 *operator*，则支持该参数。

说明：

-   可选参数 *operator* 或 *pattern* 在逗号后不能为空，只能完全省略。
-   当第三个参数为 *bitand* 时，第四个 `pattern` 参数可以指定为两个数字，并用“/”分隔：**number_to_compare_with/mask**。count\_foreach() 会对该值和 *mask* 进行“按位与”计算，并将结果与 *number_to_compare_with* 进行比较。如果“按位与”的结果等于 *number_to_compare_with*，则对该值进行计数。<br>如果 *number_to_compare_with* 和 *mask* 相等，则只需指定 *mask*（不带“/”）。
-   当第三个参数为 *regexp* 或 *iregexp* 时，第四个 `pattern` 参数可以是普通正则表达式或 [全局](/manual/regular_expressions#global-regular-expressions)（以“@”开头）正则表达式。对于全局正则表达式，大小写敏感性继承自全局正则表达式设置。出于 regexp 匹配的目的，浮点值始终会以小数点后 4 位小数的形式表示。另请注意，对于大数字，十进制（存储在数据库中）与二进制（由 Zabbix 服务器使用）表示方式之间的差异可能会影响第 4 位小数。

有关使用 foreach 函数的更多详细信息和示例，请参见[聚合计算](/manual/config/items/itemtypes/calculated/aggregate)。

[comment]: # ({/a4d91525-bf880e22})

[comment]: # ({fc23e115-328844f6})
#### 取决于可用性的行为

下表说明了在主机/监控项以及历史数据可用性受限的情况下，各个函数的行为方式。

|Function|已禁用的主机|有数据的不可用主机|无数据的不可用主机|已禁用的监控项|不支持的监控项|数据检索错误 (SQL)|
|--|--|--|--|--|--|--|
|*avg_foreach*|忽略|返回平均值|忽略|忽略|忽略|忽略|
|*bucket_rate_foreach*|忽略|返回 bucket rate|忽略|忽略|忽略|忽略|
|*count_foreach*|忽略|返回计数|0|忽略|忽略|忽略|
|*exists_foreach*|忽略|1|1|忽略|1|n/a|
|*last_foreach*|忽略|返回最后值|忽略|忽略|忽略|忽略|
|*max_foreach*|忽略|返回最大值|忽略|忽略|忽略|忽略|
|*min_foreach*|忽略|返回最小值|忽略|忽略|忽略|忽略|
|*sum_foreach*|忽略|返回总和|忽略|忽略|忽略|忽略|

如果监控项被*忽略*，则不会向聚合中添加任何内容。

[comment]: # ({/fc23e115-328844f6})
