Skip to content

Commit 61b96bc

Browse files
authored
Add toarray, todynamic, len, pack_dictionary, array_extract (#315)
1 parent 9b2c85d commit 61b96bc

File tree

8 files changed

+718
-13
lines changed

8 files changed

+718
-13
lines changed

apl/scalar-functions/array-functions.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The table summarizes the array functions available in APL.
1111
| Function | Description |
1212
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
1313
| [array_concat](/apl/scalar-functions/array-functions/array-concat) | Concatenates a number of dynamic arrays to a single array. |
14+
| [array_extract](/apl/scalar-functions/array-functions/array-extract) | Returns a dynamic array containing the extracted elements. |
1415
| [array_iff](/apl/scalar-functions/array-functions/array-iff) | Returns a new array containing elements from the input array that satisfy the condition. |
1516
| [array_index_of](/apl/scalar-functions/array-functions/array-index-of) | Searches the array for the specified item, and returns its position. |
1617
| [array_length](/apl/scalar-functions/array-functions/array-length) | Calculates the number of elements in a dynamic array. |
@@ -27,7 +28,9 @@ The table summarizes the array functions available in APL.
2728
| [bag_keys](/apl/scalar-functions/array-functions/bag-keys) | Returns all keys in a dynamic property bag. |
2829
| [bag_pack](/apl/scalar-functions/array-functions/bag-pack) | Converts a list of key-value pairs to a dynamic property bag. |
2930
| [isarray](/apl/scalar-functions/array-functions/isarray) | Checks whether a value is an array. |
31+
| [len](/apl/scalar-functions/array-functions/len) | Returns the length of a string or the number of elements in an array. |
3032
| [pack_array](/apl/scalar-functions/array-functions/pack-array) | Packs all input values into a dynamic array. |
33+
| [pack_dictionary](/apl/scalar-functions/array-functions/pack-dictionary) | Returns a dynamic object that represents a dictionary where each key maps to its associated value. |
3134
| [strcat_array](/apl/scalar-functions/array-functions/strcat-array) | Takes an array and returns a single concatenated string with the array’s elements separated by the specified delimiter. |
3235

3336
## Dynamic arrays
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
---
2+
title: array_extract
3+
description: 'This page explains how to use the array_extract function in APL.'
4+
---
5+
6+
Use the `array_extract` function to extract specific values from a dynamic array using a JSON path expression. You can use this function to transform structured array data, such as arrays of objects, into simpler arrays of scalars. This is useful when working with nested JSON-like structures where you need to extract only selected fields for analysis, visualization, or filtering.
7+
8+
Use `array_extract` when:
9+
10+
- You need to pull scalar values from arrays of objects.
11+
- You want to simplify a nested data structure before further analysis.
12+
- You are working with structured logs or metrics where key values are nested inside arrays.
13+
14+
## For users of other query languages
15+
16+
If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL.
17+
18+
<AccordionGroup>
19+
<Accordion title="Splunk SPL users">
20+
21+
In Splunk SPL, you typically use `spath` with a wildcard or field extraction logic to navigate nested structures. APL’s `array_extract` uses JSON path syntax to extract array elements that match a given pattern.
22+
23+
<CodeGroup>
24+
```sql Splunk example
25+
| eval arr=mvappend("{\"id\":1,\"value\":true}", "{\"id\":2,\"value\":false}")
26+
| spath input=arr path="{}.value" output=extracted_value
27+
````
28+
29+
```kusto APL equivalent
30+
['sample-http-logs']
31+
| extend extracted_value = array_extract(dynamic([{'id': 1, 'value': true}, {'id': 2, 'value': false}]), @'$[*].value')
32+
| project _time, extracted_value
33+
```
34+
35+
</CodeGroup>
36+
37+
</Accordion>
38+
<Accordion title="ANSI SQL users">
39+
40+
ANSI SQL doesn’t offer native support for JSON path queries on arrays in standard syntax. While some engines support functions like `JSON_VALUE` or `JSON_TABLE`, they operate on single objects. APL’s `array_extract` provides a concise and expressive way to query arrays using JSON path.
41+
42+
<CodeGroup>
43+
```sql SQL example
44+
SELECT JSON_EXTRACT(data, '$[*].value') AS extracted_value
45+
FROM my_table;
46+
```
47+
48+
```kusto APL equivalent
49+
['sample-http-logs']
50+
| extend extracted_value = array_extract(dynamic([{'id': 1, 'value': true}, {'id': 2, 'value': false}]), @'$[*].value')
51+
| project _time, extracted_value
52+
```
53+
54+
</CodeGroup>
55+
56+
</Accordion>
57+
</AccordionGroup>
58+
59+
## Usage
60+
61+
### Syntax
62+
63+
```kusto
64+
array_extract(sourceArray, jsonPath)
65+
```
66+
67+
### Parameters
68+
69+
| Name | Type | Description |
70+
| ------------- | --------- | ------------------------------------------------------- |
71+
| `sourceArray` | `dynamic` | A JSON-like dynamic array to extract values from. |
72+
| `jsonPath` | `string` | A JSON path expression to select values from the array. |
73+
74+
### Returns
75+
76+
A dynamic array of values that match the JSON path expression. The function always returns an array, even when the path matches only one element or no elements.
77+
78+
## Use case examples
79+
80+
<Tabs>
81+
<Tab title="Log analysis">
82+
83+
Use `array_extract` to retrieve specific fields from structured arrays, such as arrays of request metadata.
84+
85+
**Query**
86+
87+
```kusto
88+
['sample-http-logs']
89+
| extend extracted_value = array_extract(dynamic([{'id': 1, 'value': true}, {'id': 2, 'value': false}]), @'$[*].value')
90+
| project _time, extracted_value
91+
```
92+
93+
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20extend%20extracted_value%20%3D%20array_extract%28dynamic%28[%7B'id'%3A%201%2C%20'value'%3A%20true%7D%2C%20%7B'id'%3A%202%2C%20'value'%3A%20false%7D]%29%2C%20%40'%24%5B*%5D.value'%29%20%7C%20project%20_time%2C%20extracted_value%22%7D)
94+
95+
**Output**
96+
97+
| _time | extracted_value |
98+
| ---------------- | ------------------ |
99+
| Jun 24, 09:28:10 | ["true", "false"] |
100+
| Jun 24, 09:28:10 | ["true", "false"] |
101+
| Jun 24, 09:28:10 | ["true", "false"] |
102+
103+
This query extracts the `value` field from an array of objects, returning a flat array of booleans in string form.
104+
105+
</Tab>
106+
<Tab title="OpenTelemetry traces">
107+
108+
Use `array_extract` to extract service names from a nested structure—for example, collecting `service.name` from span records in a trace bundle.
109+
110+
**Query**
111+
112+
```kusto
113+
['otel-demo-traces']
114+
| summarize traces=make_list(pack('trace_id', trace_id, 'service', ['service.name'])) by span_id
115+
| extend services=array_extract(traces, @'$[*].service')
116+
```
117+
118+
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D%20%7C%20summarize%20traces%3Dmake_list%28pack%28'trace_id'%2C%20trace_id%2C%20'service'%2C%20%5B'service.name'%5D%29%29%20by%20span_id%20%7C%20extend%20services%3Darray_extract%28traces%2C%20%40'%24%5B*%5D.service'%29%22%7D)
119+
120+
**Output**
121+
122+
| span_id | services |
123+
| ---------------- | -------------------------------------- |
124+
| 24157518330f7967 | [frontend-proxy] |
125+
| 209a0815d291d88a | [currency] |
126+
| aca763479149f1d0 | [frontend-web] |
127+
128+
This query collects and extracts the `service.name` fields from a constructed nested structure of spans.
129+
130+
</Tab>
131+
<Tab title="Security logs">
132+
133+
Use `array_extract` to extract HTTP status codes from structured log entries grouped into sessions.
134+
135+
**Query**
136+
137+
```kusto
138+
['sample-http-logs']
139+
| summarize events=make_list(pack('uri', uri, 'status', status)) by id
140+
| extend status_codes=array_extract(events, @'$[*].status')
141+
```
142+
143+
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20summarize%20events%3Dmake_list%28pack%28'uri'%2C%20uri%2C%20'status'%2C%20status%29%29%20by%20id%20%7C%20extend%20status_codes%3Darray_extract%28events%2C%20%40'%24%5B*%5D.status'%29%22%7D)
144+
145+
**Output**
146+
147+
| id | status_codes |
148+
| ----- | ---------------------- |
149+
| user1 | [200] |
150+
| user2 | [201] |
151+
| user3 | [200] |
152+
153+
This query extracts all HTTP status codes per user session, helping to identify patterns like repeated failures or suspicious behavior.
154+
155+
</Tab>
156+
</Tabs>
157+
158+
## List of related functions
159+
160+
- [array_slice](/apl/scalar-functions/array-functions/array-slice): Returns a subarray like `array_extract`, but supports negative indexing.
161+
- [array_length](/apl/scalar-functions/array-functions/array-length): Returns the number of elements in an array. Useful before applying `array_extract`.
162+
- [array_concat](/apl/scalar-functions/array-functions/array-concat): Joins arrays end-to-end. Use before or after slicing arrays with `array_extract`.
163+
- [array_index_of](/apl/scalar-functions/array-functions/array-index-of): Finds the position of an element in an array, which can help set the `startIndex` for `array_extract`.
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
---
2+
title: len
3+
description: 'This page explains how to use the len function in APL.'
4+
---
5+
6+
Use the `len` function in APL (Axiom Processing Language) to determine the length of a string or the number of elements in an array. This function is useful when you want to filter, sort, or analyze data based on the size of a value—whether that’s the number of characters in a request URL or the number of cities associated with a user.
7+
8+
Use `len` when you need to:
9+
10+
- Measure string lengths (for example, long request URIs).
11+
- Count elements in dynamic arrays (such as tags or multi-value fields).
12+
- Create conditional expressions based on the length of values.
13+
14+
## For users of other query languages
15+
16+
If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL.
17+
18+
<AccordionGroup>
19+
<Accordion title="Splunk SPL users">
20+
21+
In Splunk SPL, you often use the `len` function within `eval` or `where` expressions to determine string length or array size. In APL, `len` works similarly, but is used as a standalone scalar function.
22+
23+
<CodeGroup>
24+
```sql Splunk example
25+
... | eval uri_length=len(uri)
26+
````
27+
28+
```kusto APL equivalent
29+
['sample-http-logs']
30+
| extend uri_length = len(uri)
31+
```
32+
33+
</CodeGroup>
34+
35+
</Accordion>
36+
<Accordion title="ANSI SQL users">
37+
38+
In ANSI SQL, you use `LENGTH()` for strings and `CARDINALITY()` for arrays. In APL, `len` handles both cases—string and array—depending on the input type.
39+
40+
<CodeGroup>
41+
```sql SQL example
42+
SELECT LENGTH(uri) AS uri_length FROM http_logs;
43+
```
44+
45+
```kusto APL equivalent
46+
['sample-http-logs']
47+
| extend uri_length = len(uri)
48+
```
49+
50+
</CodeGroup>
51+
52+
</Accordion>
53+
</AccordionGroup>
54+
55+
## Usage
56+
57+
### Syntax
58+
59+
```kusto
60+
len(value)
61+
```
62+
63+
### Parameters
64+
65+
| Name | Type | Description |
66+
| ----- | --------------- | ------------------------------------------------- |
67+
| value | string or array | The input to measure—either a string or an array. |
68+
69+
### Returns
70+
71+
- If `value` is a string, returns the number of characters.
72+
- If `value` is an array, returns the number of elements.
73+
- Returns `null` if the input is `null`.
74+
75+
## Use case examples
76+
77+
<Tabs>
78+
<Tab title="Log analysis">
79+
80+
Use `len` to find requests with long URIs, which might indicate poorly designed endpoints or potential abuse.
81+
82+
**Query**
83+
84+
```kusto
85+
['sample-http-logs']
86+
| extend uri_length = len(uri)
87+
| where uri_length > 100
88+
| project _time, id, uri, uri_length
89+
```
90+
91+
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20extend%20uri_length%20%3D%20len(uri)%20%7C%20where%20uri_length%20%3E%20100%20%7C%20project%20_time%2C%20id%2C%20uri%2C%20uri_length%22%7D)
92+
93+
**Output**
94+
95+
| _time | id | uri | uri_length |
96+
| -------------------- | ------- | --------------------------------- | ----------- |
97+
| 2025-06-18T12:34:00Z | user123 | /api/products/search?query=... | 132 |
98+
| 2025-06-18T12:35:00Z | user456 | /download/file/very/long/path/... | 141 |
99+
100+
The query filters logs for URIs longer than 100 characters and displays their lengths.
101+
102+
</Tab>
103+
<Tab title="OpenTelemetry traces">
104+
105+
Use `len` to identify traces with IDs of unexpected length, which might indicate instrumentation issues or data inconsistencies.
106+
107+
**Query**
108+
109+
```kusto
110+
['otel-demo-traces']
111+
| extend trace_id_length = len(trace_id)
112+
| summarize count() by trace_id_length
113+
```
114+
115+
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20summarize%20durations%3Dmake_list(req_duration_ms)%20by%20id%20%7C%20extend%20sorted%3Dsort_array(durations%2C%20'desc')%20%7C%20extend%20top_3%3Darray_extract(sorted%2C%200%2C%203)%22%7D)
116+
117+
**Output**
118+
119+
| trace_id_length | count |
120+
| ----------------- | ----- |
121+
| 32 | 4987 |
122+
| 16 | 12 |
123+
124+
The query summarizes trace IDs by their lengths to find unexpected values.
125+
126+
</Tab>
127+
<Tab title="Security logs">
128+
129+
Use `len` to analyze request methods and flag unusually short ones (e.g., malformed logs or attack vectors).
130+
131+
**Query**
132+
133+
```kusto
134+
['sample-http-logs']
135+
| extend method_length = len(method)
136+
| where method_length < 3
137+
| project _time, id, method, method_length
138+
```
139+
140+
[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20extend%20method_length%20%3D%20len(method)%20%7C%20where%20method_length%20%3C%203%20%7C%20project%20_time%2C%20id%2C%20method%2C%20method_length%22%7D)
141+
142+
**Output**
143+
144+
| _time | id | method | method_length |
145+
| -------------------- | ------- | ------ | -------------- |
146+
| 2025-06-18T13:10:00Z | user789 | P | 1 |
147+
| 2025-06-18T13:12:00Z | user222 | G | 1 |
148+
149+
The query finds suspicious or malformed request methods that are unusually short.
150+
151+
</Tab>
152+
</Tabs>
153+
154+
## List of related functions
155+
156+
- [array_length](/apl/scalar-functions/array-functions/array-length): Returns the number of elements in an array. Use this when working specifically with arrays.
157+
- [array_slice](/apl/scalar-functions/array-functions/array-slice): Returns a subarray like `array_extract`, but supports negative indexing.
158+
- [array_concat](/apl/scalar-functions/array-functions/array-concat): Joins arrays end-to-end. Use before or after slicing arrays with `array_extract`.

0 commit comments

Comments
 (0)