The foreach command runs a templated eval expression for each field in a field list, each element of a multivalue (array) field, or each element of a JSON array. It eliminates repetitive eval statements when the same computation applies to many fields or to every element of a collection.
The foreach command has the following syntax:
foreach [mode=<mode>] [<option>=<value>]... <target>... "[" eval <field-template> = <expression> ["," <field-template> = <expression>]... "]"The foreach command supports the following parameters.
| Parameter | Required/Optional | Description |
|---|---|---|
mode |
Optional | How the target is interpreted: multifield (iterate over matching fields), multivalue (iterate over the elements of an array field), json_array (parse a JSON array string and iterate over its elements), or auto_collections (detect multivalue or json_array automatically). Defaults to multifield, or json_array when the target is a json_array(...) function call. |
<target> |
Required for most modes | In multifield mode, one or more field names or wildcard patterns (for example, value_*). In collection modes, exactly one array field, JSON array string, or json_array(...) call. May be omitted in auto_collections mode, which then picks the first array field. |
fieldstr |
Optional | Renames the <<FIELD>> placeholder in multifield mode. |
matchstr |
Optional | Renames the <<MATCHSTR>> placeholder in multifield mode. |
itemstr |
Optional | Renames the <<ITEM>> placeholder in collection modes. |
iterstr |
Optional | Renames the <<ITER>> placeholder in collection modes. |
Inside the bracketed eval, placeholders refer to the current iteration:
| Placeholder | Mode | Meaning |
|---|---|---|
<<FIELD>> |
multifield |
The name of the current field. Usable in both the target field template and the expression. |
<<MATCHSTR>> |
multifield |
The part of the field name matched by wildcards in the pattern. |
<<ITEM>> |
collection modes | The current element of the collection. |
<<ITER>> |
collection modes | The zero-based index of the current element. |
Placeholders renamed via itemstr/iterstr may be written without the <<...>> markers in the expression.
The following considerations apply when using the foreach command:
- In collection modes, the bracketed
evalacts as an accumulator: each target field must already exist (typically initialized with a precedingeval), and the expressions are applied once per element. Multiple assignments run from left to right, so a later assignment in the same iteration sees an earlier assignment's updated value. - In
json_arraymode the element type is inferred: ajson_array(...)call or JSON string literal is inspected at plan time; for a field holding JSON text, elements are treated as numbers when<<ITEM>>is used in arithmetic and as strings otherwise. Plan-time arrays with mixed string/number elements are rejected. When numeric use is inferred for field-backed JSON text, elements that cannot be converted to numbers evaluate tonull. - Placeholders are also substituted inside string literals. For example,
eval <<FIELD>> = '<<FIELD>>'replaces each selected field value with that field's name. multivaluemode applied to a non-array value andjson_arraymode applied to a native array are no-ops. A field whose mapping is scalar cannot be identified as multivalue at plan time even when a document stores several values, somultivaluemode also no-ops for that mapping.
The following query doubles two fields using one templated eval:
source=accounts
| foreach age balance [ eval <<FIELD>>_double = <<FIELD>> * 2 ]
| fields age, age_double, balance, balance_double
| head 2
The query returns the following results:
fetched rows / total rows = 2/2
+-----+------------+---------+----------------+
| age | age_double | balance | balance_double |
|-----+------------+---------+----------------|
| 32 | 64 | 39225 | 78450 |
| 36 | 72 | 5686 | 11372 |
+-----+------------+---------+----------------+
The following query copies every field ending in name, naming each copy after the wildcard match:
source=accounts
| foreach *name [ eval copy_<<MATCHSTR>> = <<FIELD>> ]
| fields firstname, copy_first, lastname, copy_last
| head 2
The query returns the following results:
fetched rows / total rows = 2/2
+-----------+------------+----------+-----------+
| firstname | copy_first | lastname | copy_last |
|-----------+------------+----------+-----------|
| Amber | Amber | Duke | Duke |
| Hattie | Hattie | Bond | Bond |
+-----------+------------+----------+-----------+
The following query iterates over an array and accumulates a total:
source=accounts
| eval nums = array(1, 2, 3), total = 0
| foreach mode=multivalue nums [ eval total = total + <<ITEM>> ]
| fields total
| head 1
The query returns the following results:
fetched rows / total rows = 1/1
+-------+
| total |
|-------|
| 6 |
+-------+
The following query sums the indexes (0 + 1 + 2) instead of the values, renaming <<ITER>> to IDX:
source=accounts
| eval nums = array(10, 20, 30), total = 0
| foreach mode=multivalue iterstr=IDX nums [ eval total = total + IDX ]
| fields total
| head 1
The query returns the following results:
fetched rows / total rows = 1/1
+-------+
| total |
|-------|
| 3 |
+-------+
The following query parses a JSON array literal and accumulates its elements:
source=accounts
| eval total = 0
| foreach mode=json_array '[1,2,3]' [ eval total = total + <<ITEM>> ]
| fields total
| head 1
The query returns the following results:
fetched rows / total rows = 1/1
+-------+
| total |
|-------|
| 6.0 |
+-------+
json_array mode also accepts a field whose value is JSON array text, which is the common case for raw logs that embed JSON.
The following query lets auto_collections mode detect that the target is an array field:
source=accounts
| eval nums = array(1, 2, 3), total = 0
| foreach mode=auto_collections nums [ eval total = total + <<ITEM>> ]
| fields total
| head 1
The query returns the following results:
fetched rows / total rows = 1/1
+-------+
| total |
|-------|
| 6 |
+-------+
- eval --- evaluate an expression and append the result to search results
- fieldformat --- format field values for display