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.

ParameterTypeRequiredDefault ValueDescription
array[a]stringrequired   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[]", ....
asArraystringrequired value passed to the array parameter The output array — cannot be the same as the input array.
functionnon-aggregate functionrequired   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.
varstringoptional[b] input array name Name of the variable to use in the function argument.

[a] The parameter name array can be omitted.

[b] Optional parameters use their default value unless explicitly set.

Hide omitted argument names for this function

Show omitted argument names for this function

objectArray:eval() Function Operation

When using this function:

  • The variable defined by the var argument 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 function argument (see objectArray: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.baz is a valid pattern.

  • The mapping between input and output array entries is done by the function argument: for each input array entry, function maps an output array entry. The output/result value of function is the value of the same field (without []) given by the asArray argument.

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
logscale
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:

JSON
"foo[0].key.value": y
"foo[0].key.others[0]": 1
"foo[0].key.others[1]": 2
"foo[1].nothing": 355
Step-by-Step
  1. Starting with the source repository events.

  2. 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 var parameter 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.

  3. 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]": 2

Concatenate Values From Deeply Nested Array Elements

Concatenate deeply nested objects and arrays using objectArray:eval() function with itself

Query
logscale
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
  1. Starting with the source repository events.

  2. 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[].

  3. 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 the concatArray() 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 parent objectArray:eval() current array index i.

    To return the concatenated array, the asArray parameter is set to the tmp[] field, and then when we assign the value of the concatenated value.

  4. 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]: 456

Concatenate Values From Nested Array Elements

Concatenate deeply nested objects and arrays using objectArray:eval() function with concat()

Query
logscale
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:

JSON
in[0].a: 1
in[0].b.c: 2
in[0].others[0].d: 3
in[0].others[1].d: 4
Step-by-Step
  1. Starting with the source repository events.

  2. 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[].

  3. 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]: 124

Concatenate Values From Two Nested Array Elements

Concatenate values from two nested array elements returning output in flat array

Query
logscale
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:

JSON
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: abc
Step-by-Step
  1. Starting with the source repository events.

  2. logscale
    objectArray:eval("arr[]", var=x, function={_mapped := concat([x.a, x.b])}, asArray="_mapped[]")

    Concatenates the values a and b from 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 variable x which is then used as an alias. The new field _mapped is created by concatenating the value using the alias x to 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
  3. 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: abc

Count Nested Array Elements

Count elements in nested arrays using the objectArray:eval() function with array:length()

Query
logscale
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.nanosarrayToCount[0].namearrayToCount[0].valuearrayToCount[1].namearrayToCount[1].valuearrayToCount[2].namearrayToCount[2].valuearrayToCount[3].namearrayToCount[3].valuehost
"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"17749500257880alpha10beta20gamma30<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"17749500257880delta5epsilon15zeta25eta35server-02
"arrayToCount[0].name"=theta "arrayToCount[0].value"=100 "arrayToCount[1].name"=iota "arrayToCount[1].value"=200 host="server-03"17749500257880theta100iota200<no value><no value><no value><no value>server-03
"arrayToCount[0].name"=kappa "arrayToCount[0].value"=7 host="server-04"17749500257880kappa7<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"17749500257880lambda42mu84nu126xi168server-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"17749500257880omicron3pi6rho9<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"17749500257880sigma11tau22<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"17749500257880upsilon55phi110chi165psi220server-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
  1. Starting with the source repository events.

  2. 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 the array parameter, here set to arrayToCount[].

    For each element found, it evaluates the expression provided in the function parameter — in this case assigning the value true to 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 the asArray parameter.

    The results are collected into a new flat array specified by the asArray parameter, named tmpCountArray[].

    After this step, tmpCountArray[] contains one entry of true per 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.

  3. 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 one true entry 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.

  4. 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.

  5. 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:

_lengtharrayToCount[0].namearrayToCount[0].valuearrayToCount[1].namearrayToCount[1].valuearrayToCount[2].namearrayToCount[2].valuearrayToCount[3].namearrayToCount[3].valuehost
3alpha10beta20gamma30<no value><no value>server-01
4delta5epsilon15zeta25eta35server-02
2theta100iota200<no value><no value><no value><no value>server-03
1kappa7<no value><no value><no value><no value><no value><no value>server-04
4lambda42mu84nu126xi168server-05
3omicron3pi6rho9<no value><no value>server-06
2sigma11tau22<no value><no value><no value><no value>server-07
4upsilon55phi110chi165psi220server-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
logscale
"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
  1. Starting with the source repository events.

  2. logscale
    "a[0].foo" := "a"
    | "a[0].bar" := "b"
    | "a[1].foo" := "c"
    | "a[1].bar" := "d"

  3. 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 .bar to a new array output[]. This is achieved by executing an anonymous function, which sets the value of output to the iterated value of x.bar from a[].

    The asArray parameter is set to the output[] field, creating an array where each element contains the value of x.bar from the corresponding iteration.

  4. 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].fooa[0].bara[1].fooa[1].baroutput[0]output[1]
abcdbd

Format Values From Two Array Elements Using :

Format Values from Two Array Elements using : as a separator

Query
logscale
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:

JSON
in[0].key = x
in[0].value = y
in[1].key = a
in[1].value = b
Step-by-Step
  1. Starting with the source repository events.

  2. 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 var parameter 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:

    logscale
    objectArray:eval("someVeryLongName[]", asArray="out[]",
    var=x, function={out := format("%s:%s", field=[x.key,
    x.value])})
  3. 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:b

Transform 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
logscale
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].keyin[0].valuein[1].keyin[1].valuein[2].keyin[2].value@timestamp
foobarbazquxzapwham2026-03-30T08:15:00Z
alphabravocharliedeltaechofoxtrot2026-03-30T08:16:00Z
red42blue17green992026-03-30T08:17:00Z
pingpongflipflopzigzag2026-03-30T08:18:00Z
axbxcxdxexfx2026-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
  1. Starting with the source repository events.

  2. 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 the array parameter. The inner function block is applied to each element in turn. The asArray parameter 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 form key=value for 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 as foo=bar, baz=qux, and zap=wham for the first event.

  3. 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 the separator parameter. 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 as foo=bar baz=qux zap=wham.

  4. logscale
    | kvParse(field="_concatArray")

    The kvParse() function parses the space-separated key=value string stored in _concatArray, as specified by the field parameter. Each key-value pair found in the string is promoted to a top-level field on the event. For example, the string foo=bar baz=qux zap=wham results in three new fields: foo with value bar, baz with value qux, and zap with value wham. The default separator used by kvParse() is a space, which matches the output of the previous step.

  5. 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.

  6. logscale
    | array:drop("kvpairs[]")

    The array:drop() function removes the intermediate array field kvpairs[] from each event. This array was created by objectArray:eval() as a working structure to hold the formatted key=value strings and is no longer needed once parsing is complete. Using array:drop() rather than drop() is required here because kvpairs[] is an array field, and array fields must be removed with the dedicated array:drop() function.

  7. 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:

foobazzapalphacharlieechoredbluegreenpingflipzigaxcxex
barquxwham<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>bravodeltafoxtrot<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>421799<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>pongflopzag<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>bxdxfx

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.