Sub-event components in data feeds

AVAILABILITY
The functionality described in this article is in the Limited Testing phase of release and might not be available yet in your environment. This note will be removed when the functionality is generally available. For information about the Customer Journey Analytics release process, see Customer Journey Analytics feature releases.

Sub-event components are dimensions and metrics based on fields inside an array or map in your XDM schema. They allow you to analyze data at a level more granular than the event level, such as the individual products in a purchase. For information about using this data in segments, see Sub-events.

Use the following information to understand how sub-event components from array and map fields appear in your Customer Journey Analytics data feeds.

Understand sub-event components

Sub-event components in the XDM schema

In the XDM schema, each element of an array (a string array or an object array) is a sub-event. Each entry in a map field is also a sub-event, as described in Map fields in data feeds. Dimensions and metrics based on the fields within a sub-event are sub-event components.

To view sub-events within the XDM schema in Adobe Experience Platform, select Schemas, then expand an event that contains sub-events.

In the following example, Product list items is an object array containing various sub-event components.

XDM schema containing an object array and sub-event components

Sub-event differences between Analysis Workspace and data feeds

Sub-event components are represented differently between Analysis Workspace and data feeds in Customer Journey Analytics.

Location
How sub-event components are represented
Analysis Workspace (in Customer Journey Analytics)
Selectable as individual components, separate from any visible hierarchy.
Data feeds (in Customer Journey Analytics)
Represented as a group, with their hierarchy intact.

Sub-event differences between Adobe Analytics and Customer Journey Analytics

Sub-event data (such as multiple product details in a single purchase event) appears differently in Customer Journey Analytics data feeds than in Adobe Analytics data feeds. The following table compares how each product represents sub-event data.

Product
How sub-event data appears in data feeds
Example: Product list
Adobe Analytics
Flattened into a delimited string in a single column.

A product list contains multiple products grouped in a single string:

Power Tools;Cordless Drill;1;129.99,Power Tools;Drill Battery Pack;2;39.98

Customer Journey Analytics
Sub-event components retain the hierarchy defined in your XDM schema. While grouped in the same column, they show their relational hierarchy to their parent event and sibling sub-events.

A product list maintains its hierarchy that is defined in the XDM schema as an array:

[{"category":"Power Tools","product":"Cordless Drill","quantity":1,"revenue":129.99},{"category":"Power Tools","product":"Drill Battery Pack","quantity":2,"revenue":39.98}]

Sub-event example: Products in a purchase event

A customer purchases two products in a single order: one cordless drill and two drill battery packs. Your implementation sends a single purchase event that includes both products in the productListItems object array:

{
  "eventType": "commerce.purchases",
  "timestamp": "2026-09-16T14:32:07.512Z",
  "commerce": {
    "purchases": { "value": 1 }
  },
  "productListItems": [
    { "SKU": "CD-2000", "name": "Cordless Drill", "quantity": 1, "priceTotal": 129.99 },
    { "SKU": "BP-2000", "name": "Drill Battery Pack", "quantity": 2, "priceTotal": 39.98 }
  ]
}

This event contains two sub-events, one for each object in the productListItems array. The following table shows which fields belong to the event and which belong to its sub-events.

Level
Fields
What the fields describe
Event
eventType, timestamp, commerce.purchases.value
The purchase as a whole. Each field has one value for the event. The Orders metric counts 1 for this event, regardless of how many products it contains.
Sub-event
SKU, name, quantity, priceTotal in each productListItems object
An individual product in the purchase. Each field has one value per product. For example, quantity is 1 for the cordless drill and 2 for the drill battery pack.
NOTE
Sub-events include only the data that is sent with the event. Customer Journey Analytics does not reconstruct cart contents from earlier events, such as cart adds or checkouts. For products to appear as sub-events of a purchase event, your implementation must include them in productListItems on that purchase event.

Add sub-event components to a data feed

When you add a sub-event component to a data feed, a dialog prompts you to add the other components from the same sub-event.

Dialog prompting you to add related sub-event components

Fields from the same sub-event appear on the canvas as a collapsible nested group rather than a flat item.

Sub-event group

This group reflects the underlying data structure.

In the data feed output, all of these components appear as a nested array in a single column.

For information about how to add components, including sub-event components, to a data feed, see Create a data feed.

Query sub-event data in data feed output

Because sub-event data appears differently in Customer Journey Analytics data feeds, the queries you use for it differ from those you use for Adobe Analytics data feeds.

The following examples show how to find events that include a specific product. The examples use Google BigQuery syntax, where UNNEST expands an array into rows. Other data warehouses support the same approach with their own array functions, such as FLATTEN in Snowflake or explode in Databricks.

Query product data in Customer Journey Analytics data feeds

In Customer Journey Analytics data feeds, the same two products appear as an array of objects in the product_list_items column. No delimiter parsing is required:

code language-json
{
  "row_id": "01K3F2M9-...-4821",
  "timestamp_utc": "2026-09-16T14:32:07.512000Z",
  "product_list_items": [
    { "category": "Power Tools", "product": "Cordless Drill", "quantity": 1, "revenue": 129.99,
      "events": {"event1": 1}, "merchandising": {"eVar10": "DrillBundle"} },
    { "category": "Power Tools", "product": "Drill Battery Pack", "quantity": 2, "revenue": 39.98,
      "events": {"event1": 1}, "merchandising": {"eVar10": "DrillBundle"} }
  ]
}

How you write the query depends on whether you want one row per event or one row per matching product.

Return one row per event

To filter events without changing the number of rows, use an array function such as UNNEST inside an EXISTS subquery:

code language-sql
SELECT row_id, timestamp_utc, product_list_items
FROM `project.dataset.cja_data_feed` AS f
WHERE EXISTS (
  SELECT 1
  FROM UNNEST(f.product_list_items) AS item
  WHERE item.product = 'Cordless Drill'
);

This query returns one row for each matching event, with the complete product_list_items array intact, regardless of how many products in the array match.

Return one row per matching product

To return one row for each matching product, move the array function into the outer FROM clause:

code language-sql
SELECT f.row_id, f.timestamp_utc, item.product, item.quantity, item.revenue
FROM `project.dataset.cja_data_feed` AS f,
     UNNEST(f.product_list_items) AS item
WHERE item.product = 'Cordless Drill';

An event with more than one matching product appears as multiple rows, and the event’s columns, such as row_id, repeat on each row. Use this approach only when you need product-level detail. To count events in the results, use COUNT(DISTINCT row_id) instead of counting rows.

This approach applies to any array field in your XDM schema, not only products.

Query product data in Adobe Analytics data feeds

In Adobe Analytics data feeds, an event with two products purchased together appears as a single delimited string in the product_list column:

code language-text
Power Tools;Cordless Drill;1;129.99;event1=1;eVar10=DrillBundle,Power Tools;Drill Battery Pack;2;39.98;event1=1;eVar10=DrillBundle

To find events that include a Cordless Drill, you parse this string with a regular expression:

code language-sql
SELECT hitid_high, hitid_low, post_evar10
FROM aa_hit_data
WHERE REGEXP_CONTAINS(product_list, r'(^|,)[^;]*;Cordless Drill;')

Use map fields in data feeds

Map fields in your XDM schema store key-value pairs. Data feeds export each map as an array of objects, the same way as other sub-event data. Each object contains the map key and its value as separate fields.

Field names in the output come from the component IDs that you configure for the data feed, not fixed names such as key or value. The examples in this section use sample component IDs.

Simple maps

Simple maps are the map type that you can create in your own schema. Each key is a string, and each value is a string or an integer.

For example, a survey map stores each question as a key and the response as a value:

{
  "_yourtenant": {
    "surveyResponses": {
      "How did you hear about us?": "Search engine",
      "How likely are you to recommend us?": 9
    }
  }
}

In the data feed output, survey_question and survey_answer are the component IDs for the key and the value:

{
  "survey_responses": [
    { "survey_question": "How did you hear about us?", "survey_answer": "Search engine" },
    { "survey_question": "How likely are you to recommend us?", "survey_answer": 9 }
  ]
}

Identity map

Each identity in the identityMap field is exported as one object. The object contains the identity namespace (the key), along with the identifier, authenticated state, and primary flag. The namespace repeats for each identity in that namespace.

Only the identity map attributes that exist as dimensions in your data view and that you add to the data feed are exported.

{
  "identity_map": [
    { "identity_namespace": "ECID", "identity_id": "83290187457380573620940587193016478103", "authenticated_state": "ambiguous", "is_primary": true },
    { "identity_namespace": "CRMID", "identity_id": "C-1048576", "authenticated_state": "authenticated", "is_primary": false }
  ]
}

Nested maps

Some Adobe-defined fields, such as segmentMembership, are maps of maps. Data feeds flatten these into a single array, with the first-level key and second-level key as separate fields in each object. The first-level key repeats in each object it applies to, so no data or relationships are lost.

For example, segment_namespace and segment_id are the component IDs for the first-level key and the second-level key:

{
  "segment_membership": [
    { "segment_namespace": "ups", "segment_id": "04a81716-43d6-4e7a-a49c-f1d8b3129ba9", "status": "realized" },
    { "segment_namespace": "ups", "segment_id": "53cba6b2-a23b-454a-8069-fc41308f1c0f", "status": "exited" }
  ]
}
recommendation-more-help
analytics-platform-help-main