Overview

bag_pack

You typically use bag_pack in projection scenarios to consolidate structured data—for example, packing related request metadata into one field, or grouping trace data by contextual attributes. This makes it easier to output, filter, or transform nested information.

The pack and bag_pack functions are equivalent in APL.

A common use is bag_pack(*) that gets all fields of your dataset as a bag. The wildcard * is useful to match all fields in the current row, but it increases query complexity and decreases stability and performance.

Usage#

Syntax#

bag_pack(key1, value1, key2, value2, ...)

Parameters#

Name Type Description
key1, key2, ... string The names of the fields to include in the property bag.
value1, value2, ... scalar The corresponding values for the keys. Values can be of any scalar type.

The number of keys must equal the number of values. Keys must be string literals or string expressions.

Returns#

A dynamic value representing a property bag (dictionary) where keys are strings and values are the corresponding values.

Use case examples#

Use bag_pack to create a structured object that captures key request attributes for easier inspection or export.

Query

['sample-http-logs']
| where status == '500'
| project _time, error_context = bag_pack('uri', uri, 'method', method, 'duration_ms', req_duration_ms)

Run in Playground

Output

_time error_context
2025-05-27T10:00:00Z { "uri": "/api/data", "method": "GET", "duration_ms": 342 }
2025-05-27T10:05:00Z { "uri": "/api/auth", "method": "POST", "duration_ms": 879 }

The query filters HTTP logs to 500 errors and consolidates key request fields into a single dynamic column named error_context.

Use bag_pack to enrich trace summaries with service metadata for each span.

Query

['otel-demo-traces']
| where ['service.name'] == 'checkout'
| project trace_id, span_id, span_info = bag_pack('kind', kind, 'duration', duration, 'status_code', status_code)

Run in Playground

Output

trace_id span_id span_info
a1b2... f9c3... { "kind": "server", "duration": "00:00:00.1240000", "status_code": "OK" }
c3d4... h7e2... { "kind": "client", "duration": "00:00:00.0470000", "status_code": "ERROR" }

The query targets spans from the checkout and combines attributes into a single object per span.

Use bag_pack to create a compact event summary combining user ID and geographic info for anomaly detection.

Query

['sample-http-logs']
| project _time, id, geo_summary = bag_pack('city', ['geo.city'], 'country', ['geo.country'])

Run in Playground

Output

_time id geo_summary
2025-05-27T12:00:00Z user_01 { "city": "Berlin", "country": "DE" }
2025-05-27T12:01:00Z user_02 { "city": "Paris", "country": "FR" }

The query helps identify patterns in failed access attempts by summarizing location data per event.

  • bag_keys: Returns all keys in a dynamic property bag. Use it when you need to enumerate available keys.
  • bag_has_key: Checks whether a dynamic property bag contains a specific key.

Other query languages#

Splunk SPL users

In Splunk, you can use mvzip and eval to create key-value mappings, or use spath to interpret JSON data. However, packing data into a true key-value structure for export or downstream use requires JSON manipulation. APL’s bag_pack provides a native and type-safe way to do this.

Splunk example

| eval metadata=tojson({"status": status, "duration": req_duration_ms})

APL equivalent

project metadata = bag_pack('status', status, 'duration', req_duration_ms)
ANSI SQL users

SQL doesn’t have a direct built-in function like bag_pack. To achieve similar behavior, you typically construct JSON objects using functions like JSON_OBJECT or use user-defined types. In APL, bag_pack is the idiomatic way to construct dynamic objects with labeled fields.

SQL example

SELECT JSON_OBJECT('status' VALUE status, 'duration' VALUE req_duration_ms) AS metadata FROM logs;

APL equivalent

project metadata = bag_pack('status', status, 'duration', req_duration_ms)

Updated

Was this page helpful?