Composite topics are currently in beta. Reach out to your Omni contact or Omni support to opt into the beta.
A few worked composite topics you can adapt. For the full reference of every parameter, see Composite topic parameters.
Complete example
A composite topic using the most common parameters:
Full composite topic example
topics: [orders_topic, marketing_topic]
label: "Orders & Marketing"
description: "Revenue and marketing performance, aligned by date and region"
shared_views: [date_spine, regions]
shared_dimensions:
activity_date:
label: "Activity date"
description: "Date the order was placed or the campaign was active"
ai_context: "Use this for any time-series comparison between orders and marketing."
mappings:
orders_topic:
field: orders.created_at
marketing_topic:
field: campaigns.start_date
region:
label: "Region"
mappings:
orders_topic:
field: regions.region_name
marketing_topic:
field: regions.region_name
shared_measures:
revenue_per_dollar_spent:
label: "Revenue per $ spent"
sql: ${@orders_topic.orders.total_revenue} / NULLIF(${@marketing_topic.campaigns.total_spend}, 0)
format: usdcurrency_2
combined_event_count:
label: "Total events"
sql: ${@orders_topic.orders.count} + ${@marketing_topic.campaigns.count}
Shared measures take plain math over already-aggregated values — arithmetic, CASE, COALESCE, NULLIF, etc. See shared_measures for details.
Orders vs. shipments by week
A classic fan-out scenario: every order has one or more shipments. Joining directly inflates order revenue.
orders_and_shipments.composite_topic
topics: [orders_topic, shipments_topic]
label: "Orders & Shipments"
shared_dimensions:
week:
label: "Week"
mappings:
orders_topic:
field: orders.created_at
shipments_topic:
field: shipments.shipped_at
shared_measures:
fulfillment_rate:
label: "Fulfillment rate"
sql: ${@shipments_topic.shipments.count} / NULLIF(${@orders_topic.orders.count}, 0)
format: percent_2
Pick Week, Orders → Total revenue, Shipments → Shipment count, and Fulfillment rate in a workbook — one row per week, all four columns correctly computed.
Marketing funnel across systems
Each funnel stage lives in its own topic (separate fact tables in different schemas). The composite topic stitches them together by cohort week.
acquisition_funnel.composite_topic
topics: [signups_topic, trials_topic, conversions_topic, churn_topic]
label: "Acquisition funnel"
shared_dimensions:
cohort_week:
label: "Cohort week"
mappings:
signups_topic:
field: signups.signed_up_at
trials_topic:
field: trials.started_at
conversions_topic:
field: conversions.converted_at
churn_topic:
field: churn_events.churned_at
shared_measures:
trial_to_paid_rate:
label: "Trial → paid"
sql: ${@conversions_topic.conversions.count} / NULLIF(${@trials_topic.trials.count}, 0)
format: percent_2
net_new_customers:
label: "Net new customers"
sql: ${@conversions_topic.conversions.count} - ${@churn_topic.churn_events.count}
Constellation schema with a date spine
When you want to chart multiple fact tables alongside a continuous date axis (no gaps for days with zero activity), use a date_spine shared view.
daily_kpis.composite_topic
topics: [orders_topic, support_topic, product_usage_topic]
label: "Daily KPIs"
shared_views: [date_spine]
Because date_spine is a shared view joined into every topic, every day appears in the result — even days with no orders, no tickets, or no usage events.