Use the bag_zip function in APL to combine two arrays—one containing keys and another containing values—into a single dynamic property bag (dictionary). This is useful when you have parallel arrays that you want to merge into a structured key-value object for easier manipulation or output.
You typically use bag_zip when parsing data that arrives as separate lists of keys and values, or when transforming array-based structures into more readable dictionary formats. This function is especially helpful in log analysis, data transformation pipelines, and when preparing data for downstream systems that expect key-value pairs.
For users of other query languages
If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL.
In Splunk SPL, you use mvzip to combine two multi-value fields into paired elements. APL's bag_zip goes further by creating a true dictionary object from separate key and value arrays.
['sample-http-logs']
| extend keys = dynamic(['status', 'method', 'city'])
| extend values = dynamic(['200', 'GET', 'Seattle'])
| extend result = bag_zip(keys, values)ANSI SQL doesn't have native support for combining arrays into key-value dictionaries. You typically need to use JSON functions or complex CASE statements to achieve similar results. APL's bag_zip provides a direct and type-safe way to perform this operation.
['sample-http-logs']
| extend keys = dynamic(['key1', 'key2'])
| extend values = dynamic([value1, value2])
| extend result = bag_zip(keys, values)Usage
Syntax
bag_zip(keys, values)Parameters
| Name | Type | Description |
|---|---|---|
keys |
dynamic |
An array of strings representing the keys for the resulting property bag. |
values |
dynamic |
An array of values corresponding to the keys. Can contain any data type. |
Returns
A dynamic property bag (dictionary) where each key from the keys array is paired with the corresponding value from the values array. If the arrays have different lengths, the function pairs elements up to the length of the shorter array and ignores any extra elements.
Use case examples
Use bag_zip to combine metadata keys and values extracted from HTTP logs into structured objects for easier analysis.
Query
['sample-http-logs']
| extend metadata_keys = dynamic(['status_code', 'request_method', 'city'])
| extend metadata_values = pack_array(status, method, ['geo.city'])
| extend request_metadata = bag_zip(metadata_keys, metadata_values)
| project _time, uri, request_metadata
| take 5Output
| _time | uri | request_metadata |
|---|---|---|
| 2025-05-26 10:15:30 | /api/user | {status_code: 200, request_method: GET, city: Seattle} |
| 2025-05-26 10:16:45 | /api/data | {status_code: 404, request_method: POST, city: Portland} |
This query creates structured metadata objects by zipping together field names and their corresponding values, making the data easier to export or process downstream.
Use bag_zip to construct custom span attributes from separate attribute name and value arrays in OpenTelemetry traces.
Query
['otel-demo-traces']
| extend attr_keys = dynamic(['service', 'span_kind', 'status'])
| extend attr_values = pack_array(['service.name'], kind, status_code)
| extend span_attributes = bag_zip(attr_keys, attr_values)
| project _time, span_id, trace_id, span_attributes
| take 5Output
| _time | span_id | trace_id | span_attributes |
|---|---|---|---|
| 2025-05-26 11:20:15 | a1b2c3d4e5f6 | xyz123abc456 | {service: frontend, span_kind: server, status: OK} |
| 2025-05-26 11:21:30 | f6e5d4c3b2a1 | def789ghi012 | {service: cart, span_kind: client, status: OK} |
This query consolidates span-level metadata into structured attribute dictionaries, simplifying trace analysis and visualization.
Use bag_zip to create structured security context objects from arrays of security-related field names and values.
Query
['sample-http-logs']
| extend security_keys = dynamic(['client_ip', 'country', 'http_status'])
| extend security_values = pack_array(id, ['geo.country'], status)
| extend security_context = bag_zip(security_keys, security_values)
| where status != '200'
| project _time, uri, method, security_context
| take 5Output
| _time | uri | method | security_context |
|---|---|---|---|
| 2025-05-26 12:30:00 | /admin/panel | POST | {client_ip: user123, country: CN, http_status: 403} |
| 2025-05-26 12:31:15 | /api/delete | DELETE | {client_ip: user456, country: RU, http_status: 401} |
This query creates structured security context for failed requests, making it easier to analyze security incidents and audit access patterns.
List of related functions
- bag_pack: Use
bag_packwhen you have key-value pairs as separate arguments rather than arrays. Usebag_zipwhen working with parallel arrays. - bag_keys: Use
bag_keysto extract all keys from an existing property bag. Usebag_zipto create a new property bag from separate key and value arrays. - pack_dictionary: Similar to
bag_zip, butpack_dictionarytakes alternating key-value arguments. Usebag_zipfor array-based inputs. - todynamic: Use
todynamicto parse JSON strings into dynamic objects. Usebag_zipto construct dynamic objects programmatically from arrays.