objectArray:eval() function iterates over
the values of a nested array, applies the function on each
element, and returns results in a new array field. Currently,
the function supports only flat arrays as the output.
Although objectArray:eval() can be used on
both flat arrays and nested arrays, then for best performance,
we recommend using objectArray:eval() only
for nested arrays (for example JSON structures). For flat
arrays, the array:eval() function is a
recommended equivalent. For a list of functions that can be used
on flat arrays, see Array Query Functions.
| Parameter | Type | Required | Default Value | Description |
|---|---|---|---|---|
array[a] | string | required | The array name in LogScale Array Syntax, for example, for events with fields incidents[0], incidents[1], ... this would be incidents[], as in objectArray:eval(array="incidents[]", .... | |
asArray | string | required | value passed to the array parameter | The output array — cannot be the same as the input array. |
function | non-aggregate function | required | The function applied to each element of the array. This argument is used to write a value to the same field that is given as the output array in the asArray argument. In objectArray:eval() Examples, such a field is _mapped. | |
var | string | optional[b] | input array name | Name of the variable to use in the function argument. |
[b] Optional parameters use their default value unless explicitly set. | ||||
Hide omitted argument names for this function
Omitted Argument NamesThe argument name for
arraycan be omitted; the following forms of this function are equivalent:logscale SyntaxobjectArray:eval("value",asArray=value passed to the array parameter,function="value")and:
logscale SyntaxobjectArray:eval(array="value",asArray=value passed to the array parameter,function="value")These examples show basic structure only.
objectArray:eval() Function Operation
When using this function:
The variable defined by the
varargument is validated to ensure it does not contain object/array access patterns, for example,[..]or..The variable becomes available as a "pseudo-field" (meaning that it's not like a proper field in the event) in the
functionargument (seeobjectArray:eval()Examples).The "pseudo-field" can access structured data on the array entries using an array access pattern consisting of
[number]for array indexing and.for sub-selections of object fields. These can be repeated/combined arbitrarily; for example,x.foo[0].bar.bazis a valid pattern.The mapping between input and output array entries is done by the
functionargument: for each input array entry,functionmaps an output array entry. The output/result value offunctionis the value of the same field (without[]) given by theasArrayargument.
objectArray:eval() Examples
Click next to an example below to get the full details.
Concatenate Multiple Values From Nested Array Elements
Concatenate multiple values from nested array elements using
objectArray:eval() function with
concat()
Query
objectArray:eval("foo[]", var=x, function={_mapped := concat([x.key.value, "x.key.others[0]", "x.key.others[1]"])}, asArray="_mapped[]")Introduction
In this example, the objectArray:eval() function is
used with the concat() function to concatenate
multiple deeply nested arrays of objects values in the array
foo[] and return the concatenated
values in the output field
_mapped[]
Example incoming data might look like this:
"foo[0].key.value": y
"foo[0].key.others[0]": 1
"foo[0].key.others[1]": 2
"foo[1].nothing": 355Step-by-Step
Starting with the source repository events.
- logscale
objectArray:eval("foo[]", var=x, function={_mapped := concat([x.key.value, "x.key.others[0]", "x.key.others[1]"])}, asArray="_mapped[]")Notice that a
varparameter can be used to give a different name to the input array variable inside the function argument. This is particularly useful whenever the input array name is very long. Event Result set.
Summary and Results
The query is used to concatenate multiple deeply nested arrays of objects values.
Sample output from the incoming example data:
_mapped[0]: y12
"foo[0].key.value": y
"foo[0].key.others[0]": 1
"foo[0].key.others[1]": 2Concatenate Values From Deeply Nested Array Elements
Concatenate deeply nested objects and arrays using
objectArray:eval() function with itself
Query
objectArray:eval(
"in[]",
asArray="out[]",
function={
objectArray:eval("in.others[]", asArray="tmp[]", function={tmp := "in.others.d"})
| out := concatArray(tmp)
}
)Introduction
In this example, the objectArray:eval() function is
used with itself to concatenate a deeply nested arrays of objects values
in the array in[] and return the
concatenated values in the output field
out[].
Example incoming data might look like this:
| in[0].others[0].d: 1 |
|---|
| in[0].others[1].d: 2 |
| in[0].others[2].d: 3 |
| in[1].others[0].d: 4 |
| in[1].others[1].d: 5 |
| in[1].others[2].d: 6 |
Step-by-Step
Starting with the source repository events.
- logscale
objectArray:eval( "in[]", asArray="out[]", function={Iterates over the array from start to end (or to the first empty index in the array, applies the given function, and returns the concatenated results in a new output array name field out[].
- logscale
objectArray:eval("in.others[]", asArray="tmp[]", function={tmp := "in.others.d"}) | out := concatArray(tmp) } )The nested
objectArray:eval()performs the concatenation of the values within the nested array by calling theconcatArray()function.Notice that in the nested call to
objectArray:eval(), the given input array name is the nested array in.others[]. This works because it is translated to the field in[i].others[] by the parentobjectArray:eval()current array indexi.To return the concatenated array, the
asArrayparameter is set to the tmp[] field, and then when we assign the value of the concatenated value. Event Result set.
Summary and Results
The query is used to concatenate deeply nested arrays of objects. The use of this function in this way is often useful when incoming ingested data has been defined in a nested structure, but needs to be displayed or summarized. For example, importing the properties or configuration values may result in a list of potential values for a given property. Concatenating the values together makes them easier to use as a summary value for display in a table or graph.
Sample output from the incoming example data:
out[0]: 123
out[1]: 456Concatenate Values From Nested Array Elements
Concatenate deeply nested objects and arrays using
objectArray:eval() function with
concat()
Query
objectArray:eval("in[]", asArray="out[]", function={out := concat(["in.a", "in.b.c", "in.others[1].d"])})Introduction
In this example, the objectArray:eval() function is
used with the concat() function to concatenate
deeply nested arrays of objects values in the array
in[] and return the concatenated
values in the output field
out[].
Example incoming data might look like this:
in[0].a: 1
in[0].b.c: 2
in[0].others[0].d: 3
in[0].others[1].d: 4Step-by-Step
Starting with the source repository events.
- logscale
objectArray:eval("in[]", asArray="out[]", function={out := concat(["in.a", "in.b.c", "in.others[1].d"])})Iterates over the array from start to end (or to the first empty index in the array), applies the given function, and returns the concatenated results in a new output array name field out[].
Event Result set.
Summary and Results
The query is used to concatenate deeply nested arrays of objects.
Sample output from the incoming example data:
out[0]: 124Concatenate Values From Two Nested Array Elements
Concatenate values from two nested array elements returning output in flat array
Query
objectArray:eval("arr[]", var=x, function={_mapped := concat([x.a, x.b])}, asArray="_mapped[]")Introduction
In this example, the objectArray:eval() function is
used with the variable x to
concatenate the values a and
b from each array element. The
concat() function is used to return the
concatenated output into a new array.
Example incoming data might look like this:
arr[0]: machine
arr[0].a: a0
arr[0].b: b0
arr[1].a: a1
arr[1].b: b1
arr[1].c: c1
arr[2].a: a2
arr[4].b: b2
other: abcStep-by-Step
Starting with the source repository events.
- logscale
objectArray:eval("arr[]", var=x, function={_mapped := concat([x.a, x.b])}, asArray="_mapped[]")Concatenates the values
aandbfrom each array element and returns the results in a new array named _mapped. In this example,objectArray:eval()iterates over each element of the array and assigns each element to the variablexwhich is then used as an alias. The new field _mapped is created by concatenating the value using the aliasxto extract each object value from each element of the array. Notice that the output in this example is a flat array.For example, this array element:
arr[0].a: a0 arr[0].b: b0 is translated to:
_mapped[0]: a0b0 Event Result set.
Summary and Results
The query is used to concatenate values of two array elements.
Sample output from the incoming example data, the original values have not been removed:
_mapped[0]: a0b0
_mapped[1]: a1b1
_mapped[2]: a2
_mapped[3]: b2
arr[0]: machine
arr[0].a: a0
arr[0].b: b0
arr[1].a: a1
arr[1].b: b1
arr[1].c: c1
arr[2].a: a2
arr[4].b: b2
other: abcCount Nested Array Elements
Count elements in nested arrays using the
objectArray:eval() function with
array:length()
Query
objectArray:eval(array="arrayToCount[]", asArray="tmpCountArray[]", function={ tmpCountArray:=true })
| array:length("tmpCountArray[]")
| array:drop("tmpCountArray[]")Introduction
In this example, the objectArray:eval() function is
used to iterate over a nested array field named
arrayToCount[] and populate a temporary flat array
named tmpCountArray[] with a marker value of
true for each element. This enables
array:length() to count the number of nested array
elements, which it otherwise cannot do directly on object arrays.
Example incoming data might look like this:
| @rawstring | @timestamp | @timestamp.nanos | arrayToCount[0].name | arrayToCount[0].value | arrayToCount[1].name | arrayToCount[1].value | arrayToCount[2].name | arrayToCount[2].value | arrayToCount[3].name | arrayToCount[3].value | host |
|---|---|---|---|---|---|---|---|---|---|---|---|
| "arrayToCount[0].name"=alpha "arrayToCount[0].value"=10 "arrayToCount[1].name"=beta "arrayToCount[1].value"=20 "arrayToCount[2].name"=gamma "arrayToCount[2].value"=30 host="server-01" | 1774950025788 | 0 | alpha | 10 | beta | 20 | gamma | 30 | <no value> | <no value> | server-01 |
| "arrayToCount[0].name"=delta "arrayToCount[0].value"=5 "arrayToCount[1].name"=epsilon "arrayToCount[1].value"=15 "arrayToCount[2].name"=zeta "arrayToCount[2].value"=25 "arrayToCount[3].name"=eta "arrayToCount[3].value"=35 host="server-02" | 1774950025788 | 0 | delta | 5 | epsilon | 15 | zeta | 25 | eta | 35 | server-02 |
| "arrayToCount[0].name"=theta "arrayToCount[0].value"=100 "arrayToCount[1].name"=iota "arrayToCount[1].value"=200 host="server-03" | 1774950025788 | 0 | theta | 100 | iota | 200 | <no value> | <no value> | <no value> | <no value> | server-03 |
| "arrayToCount[0].name"=kappa "arrayToCount[0].value"=7 host="server-04" | 1774950025788 | 0 | kappa | 7 | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | server-04 |
| "arrayToCount[0].name"=lambda "arrayToCount[0].value"=42 "arrayToCount[1].name"=mu "arrayToCount[1].value"=84 "arrayToCount[2].name"=nu "arrayToCount[2].value"=126 "arrayToCount[3].name"=xi "arrayToCount[3].value"=168 host="server-05" | 1774950025788 | 0 | lambda | 42 | mu | 84 | nu | 126 | xi | 168 | server-05 |
| "arrayToCount[0].name"=omicron "arrayToCount[0].value"=3 "arrayToCount[1].name"=pi "arrayToCount[1].value"=6 "arrayToCount[2].name"=rho "arrayToCount[2].value"=9 host="server-06" | 1774950025788 | 0 | omicron | 3 | pi | 6 | rho | 9 | <no value> | <no value> | server-06 |
| "arrayToCount[0].name"=sigma "arrayToCount[0].value"=11 "arrayToCount[1].name"=tau "arrayToCount[1].value"=22 host="server-07" | 1774950025788 | 0 | sigma | 11 | tau | 22 | <no value> | <no value> | <no value> | <no value> | server-07 |
| "arrayToCount[0].name"=upsilon "arrayToCount[0].value"=55 "arrayToCount[1].name"=phi "arrayToCount[1].value"=110 "arrayToCount[2].name"=chi "arrayToCount[2].value"=165 "arrayToCount[3].name"=psi "arrayToCount[3].value"=220 host="server-08" | 1774950025788 | 0 | upsilon | 55 | phi | 110 | chi | 165 | psi | 220 | server-08 |
Each event contains a nested array field
arrayToCount[], where each element is an object
with sub-fields such as arrayToCount[n].name and
arrayToCount[n].value. Because the array elements
are objects rather than scalar values,
array:length() alone cannot count them. The
workaround described in this example resolves this limitation.
Step-by-Step
Starting with the source repository events.
- logscale
objectArray:eval(array="arrayToCount[]", asArray="tmpCountArray[]", function={ tmpCountArray:=true })The
objectArray:eval()function iterates over each element of the nested object array specified by thearrayparameter, here set to arrayToCount[].For each element found, it evaluates the expression provided in the
functionparameter — in this case assigning the valuetrueto a field named tmpCountArray, which will be an element of the output array. Note that the field name must match the array name specified in theasArrayparameter.The results are collected into a new flat array specified by the
asArrayparameter, named tmpCountArray[].After this step, tmpCountArray[] contains one entry of
trueper element in the original nested array arrayToCount[], effectively creating a flat, countable representation of the nested array's length. Without this intermediate step,array:length()would be unable to count the elements because it does not operate on object-type (nested) arrays.Note that the temporary array (in this example tmpCountArray[]) must have a unique name for each searched event. If the name is not unique, LogScale overwrites and drops existing fields from the event.
- logscale
| array:length("tmpCountArray[]")The
array:length()function counts the number of elements in the flat array tmpCountArray[] that was created in the previous step. Because tmpCountArray[] is a flat array with onetrueentry per original nested element, this count accurately reflects the number of elements in the original nested array arrayToCount[]. The function returns the result in a new field named _length by default. - logscale
| array:drop("tmpCountArray[]")Removes the temporary flat array tmpCountArray[] from the event. Since this array was only created as an intermediate step to enable counting, it is no longer needed once
array:length()has returned the count in the _length field. Dropping it keeps the output clean and avoids polluting the results with intermediate fields. Event Result set.
Summary and Results
The query is used to count the number of elements in a nested object
array field by using the objectArray:eval()
function to create a temporary flat array of marker values, then
applying the array:length() function to find the
length of the flat temporary array, and finally removing the temporary
array with array:drop().
This query is useful, for example, to determine how many sub-objects are
present in a nested array field per event — such as counting the
number of items in a shopping cart, the number of network interfaces on
a host, or the number of findings in a security alert — in cases
where the array:length() function alone cannot
operate on object arrays.
Sample output from the incoming example data:
| _length | arrayToCount[0].name | arrayToCount[0].value | arrayToCount[1].name | arrayToCount[1].value | arrayToCount[2].name | arrayToCount[2].value | arrayToCount[3].name | arrayToCount[3].value | host |
|---|---|---|---|---|---|---|---|---|---|
| 3 | alpha | 10 | beta | 20 | gamma | 30 | <no value> | <no value> | server-01 |
| 4 | delta | 5 | epsilon | 15 | zeta | 25 | eta | 35 | server-02 |
| 2 | theta | 100 | iota | 200 | <no value> | <no value> | <no value> | <no value> | server-03 |
| 1 | kappa | 7 | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | server-04 |
| 4 | lambda | 42 | mu | 84 | nu | 126 | xi | 168 | server-05 |
| 3 | omicron | 3 | pi | 6 | rho | 9 | <no value> | <no value> | server-06 |
| 2 | sigma | 11 | tau | 22 | <no value> | <no value> | <no value> | <no value> | server-07 |
| 4 | upsilon | 55 | phi | 110 | chi | 165 | psi | 220 | server-08 |
Note that the original nested array fields
arrayToCount[] are still present in the output
alongside host and _length
— only the intermediate tmpCountArray[] field
has been removed by array:drop().
Also note that the count in _length reflects only
the number of populated elements in the nested array per event, so
events with fewer sub-objects will return a lower count accordingly, as
seen with server-04 which contains only a single
nested array element and therefore returns a
_length value of 1.
Create Single Array from Object Arrays
Transform one or more objects from object arrays into a single array
Query
"a[0].foo" := "a"
| "a[0].bar" := "b"
| "a[1].foo" := "c"
| "a[1].bar" := "d"
| objectArray:eval(array="a[]", asArray="output[]", var="x", function={output := x.bar})Introduction
In this example, the objectArray:eval() function is
used to extract one object from each element of an array of objects into
a new array.
Example incoming data might look like this:
| a[0].foo: a |
|---|
| a[0].bar: b |
| a[1].foo: c |
| a[1].bar: d |
Step-by-Step
Starting with the source repository events.
- logscale
"a[0].foo" := "a" | "a[0].bar" := "b" | "a[1].foo" := "c" | "a[1].bar" := "d" - logscale
| objectArray:eval(array="a[]", asArray="output[]", var="x", function={output := x.bar})Iterates (creates a loop) over the array
a[]and adds the value of the object.barto a new arrayoutput[]. This is achieved by executing an anonymous function, which sets the value ofoutputto the iterated value ofx.barfroma[].The
asArrayparameter is set to the output[] field, creating an array where each element contains the value of x.bar from the corresponding iteration. Event Result set.
Summary and Results
The query is used to create an array from compound arrays. This can be useful when you need to collect specific values from nested arrays for further processing, filtering, or analysis.
Sample output from the incoming example data:
| a[0].foo | a[0].bar | a[1].foo | a[1].bar | output[0] | output[1] |
|---|---|---|---|---|---|
| a | b | c | d | b | d |
Format Values From Two Array Elements Using :
Format Values from Two Array Elements using : as a separator
Query
objectArray:eval("in[]", asArray="out[]", function={out := format("%s:%s", field=[in.key, in.value])})Introduction
In this example, the objectArray:eval() function is
used to format the array entries in[].key
and in[].value
separating the concatenated values with a
: in the output field
out[]. The output must be a
single field in this example as format() is only
capable of creating a single value.
Example incoming data might look like this:
in[0].key = x
in[0].value = y
in[1].key = a
in[1].value = bStep-by-Step
Starting with the source repository events.
- logscale
objectArray:eval("in[]", asArray="out[]", function={out := format("%s:%s", field=[in.key, in.value])})Iterates (executes a loop) over the array from start to end (or to the first empty index in the array), applies the given function, and returns the concatenated results in a new output array name field out[].
Notice that a
varparameter can be used to give a different name to the input array variable inside the function argument. This is particularly useful whenever the input array name is very long. Example:logscaleobjectArray:eval("someVeryLongName[]", asArray="out[]", var=x, function={out := format("%s:%s", field=[x.key, x.value])}) Event Result set.
Summary and Results
The query is used to format arrays of objects.
Sample output from the incoming example data:
out[0] = x:y
out[1] = a:bTransform Array Key-Value Pairs Into Top-Level Fields
Flatten structured array data into individual fields using the
objectArray:eval() with
concatArray() and
array:drop()
Query
objectArray:eval(array="in[]", asArray="kvpairs[]", function={
kvpairs:=format("%s=%s", field=[in.key, in.value])
})
| concatArray("kvpairs", separator=" ")
| kvParse(field="_concatArray")
| drop([_concatArray])
| array:drop("kvpairs[]")Introduction
In this example, the objectArray:eval() function is
used to iterate over an array of key-value pair objects stored in the
in[] array field, formatting each pair into a
key=value string. The resulting strings are then
concatenated into a single space-separated string, parsed with
kvParse() to promote each key-value pair into a
top-level field, and finally the intermediate working fields are removed
using drop() and array:drop().
Example incoming data might look like this:
| in[0].key | in[0].value | in[1].key | in[1].value | in[2].key | in[2].value | @timestamp |
|---|---|---|---|---|---|---|
| foo | bar | baz | qux | zap | wham | 2026-03-30T08:15:00Z |
| alpha | bravo | charlie | delta | echo | foxtrot | 2026-03-30T08:16:00Z |
| red | 42 | blue | 17 | green | 99 | 2026-03-30T08:17:00Z |
| ping | pong | flip | flop | zig | zag | 2026-03-30T08:18:00Z |
| ax | bx | cx | dx | ex | fx | 2026-03-30T08:19:00Z |
Each event contains an array of objects under the in[] field, where each object has a key and a value sub-field. The goal is to promote these dynamic key-value pairs into individual top-level fields on each event, regardless of what the key names are.
Step-by-Step
Starting with the source repository events.
- logscale
objectArray:eval(array="in[]", asArray="kvpairs[]", function={ kvpairs:=format("%s=%s", field=[in.key, in.value]) })The
objectArray:eval()function iterates over each element in the in[] array, as specified by thearrayparameter. The inner function block is applied to each element in turn. TheasArrayparameter specifies that the results of the inner function are collected into a new array named kvpairs[], updating the event with this new array field.Inside the function block, the
format()function constructs a string in the formkey=valuefor each array element by referencing in.key and in.value — the sub-fields of each object in the in[] array. The result is assigned to kvpairs for each iteration, producing an array of formatted strings such asfoo=bar,baz=qux, andzap=whamfor the first event. - logscale
| concatArray("kvpairs", separator=" ")The
concatArray()function joins all elements of the kvpairs[] array into a single string, using a space character as the separator specified by theseparatorparameter. The result is returned in a new field named _concatArray, which is the default output field name for this function. For the first event, this produces a string such asfoo=bar baz=qux zap=wham. - logscale
| kvParse(field="_concatArray")The
kvParse()function parses the space-separatedkey=valuestring stored in _concatArray, as specified by thefieldparameter. Each key-value pair found in the string is promoted to a top-level field on the event. For example, the stringfoo=bar baz=qux zap=whamresults in three new fields: foo with valuebar, baz with valuequx, and zap with valuewham. The default separator used bykvParse()is a space, which matches the output of the previous step. - logscale
| drop([_concatArray])The
drop()function removes the intermediate scalar field _concatArray from each event. This field was only needed as an intermediate representation during the parsing step and is no longer required in the final output. - logscale
| array:drop("kvpairs[]")The
array:drop()function removes the intermediate array field kvpairs[] from each event. This array was created byobjectArray:eval()as a working structure to hold the formattedkey=valuestrings and is no longer needed once parsing is complete. Usingarray:drop()rather thandrop()is required here because kvpairs[] is an array field, and array fields must be removed with the dedicatedarray:drop()function. Event Result set.
Summary and Results
The query is used to flatten structured array data — where each
array element is an object containing a key and a
value sub-field — into individual top-level
fields on each event. It achieves this by iterating over the array with
objectArray:eval(), formatting each pair as a
key=value string, concatenating the strings with
concatArray(), parsing the result with
kvParse(), and finally cleaning up the intermediate
scalar field with drop() and the intermediate array
field with array:drop().
This query is useful, for example, to normalize events from systems that emit dynamic or variable sets of attributes as arrays of key-value objects — such as configuration management tools, metadata APIs, or enrichment pipelines — so that the attributes can be used directly in filters, aggregations, and dashboards without requiring knowledge of the specific key names in advance.
Sample output from the incoming example data:
| foo | baz | zap | alpha | charlie | echo | red | blue | green | ping | flip | zig | ax | cx | ex |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| bar | qux | wham | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> |
| <no value> | <no value> | <no value> | bravo | delta | foxtrot | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> |
| <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | 42 | 17 | 99 | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> |
| <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | pong | flop | zag | <no value> | <no value> | <no value> |
| <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | <no value> | bx | dx | fx |
Note that each event only contains values for the fields that were present in its own in[] array — fields from other events are absent for that row, since the key names are dynamic and differ between events. The field names in the output are entirely determined by the values of the key sub-fields in the input array, making this pattern flexible for any set of dynamic attribute names.