Skip to main content
Composite topics are currently in beta. Reach out to your Omni contact or Omni support to opt into the beta.

Requirements

To follow this guide, you’ll need:
  • Composite topics enabled on your instance. To opt into the beta, reach out to your Omni contact or Omni support.
  • At least Modeler permissions to create a composite topic in the shared model
  • At least two existing topics that share at least one logical dimension (date, customer ID, region, etc.)

Create the composite topic

1

Create the file

Composite topics live in their own file with the .composite_topic extension.For many use cases, the create flow alone is enough — save the file and skip to Save and use the composite topic. The remaining steps cover optional refinements.
  1. Open the Model IDE.
  2. Click File > New Composite topic.
  3. Enter a name. This becomes the filename and the unique identifier — for example, revenue_and_spend.
  4. Pick the topics you want to combine.
  5. Optional. Choose whether Omni should auto-detect shared views across the topics.
  6. Optional. Add a Group Label.
  7. Click Create.
Omni creates a <name>.composite_topic file with:
  • The topics: list you picked
  • Optional. A shared_views: list auto-populated with any dimension tables that are joinable from every included topic
2

Optional: Refine shared views

A shared view is a dimension table joinable from every topic — typically a date spine, region table, or product catalog. Omni auto-detects them on file creation; edit the list as needed:
Refining shared_views
topics: [orders_topic, marketing_topic]
shared_views: [date_spine, regions]   # auto-detected; remove or add as needed
Each shared view must be joinable from every included topic — either as the base view of every topic or through the model’s relationships. The validator surfaces an error otherwise.Any topic can use a shared view’s dimensions as join keys. Measures on a shared view are aggregated per topic, not combined — for example, if both an orders topic and a marketing topic use a shared regions view, the field picker shows a separate region count for each topic instead of one shared total.
3

Optional: Add shared dimensions

Shared dimensions handle the case where each topic has its own field for the same logical concept but at a different path.
You don’t need a shared dimension for a field that already lives in a shared view — the shared view’s columns are usable as join keys directly.
To define shared dimensions, use the mappings: syntax — each topic name is a key, and each value is the field path within that topic:
orders_and_marketing.composite_topic
topics: [orders_topic, marketing_topic]
label: "Revenue & Marketing"

shared_dimensions:
  activity_date:
    label: "Activity date"
    description: "Aligns orders and marketing activity by day"
    mappings:
      orders_topic:
        field: orders.created_at
      marketing_topic:
        field: campaigns.start_date
The shared dimension activity_date becomes a single selectable field in the workbook. When a user picks it, Omni includes orders.created_at in the orders subquery and campaigns.start_date in the marketing subquery, then joins on the resulting columns.
4

Optional: Add shared measures

A shared measure combines values from multiple topics in a single SQL expression. Define it in the shared_measures: block and reference topic-scoped fields with ${@topic_name.view.field}.
Get the exact ${@topic.view.field} reference from the field picker. Open a workbook on the composite topic, find the measure you want to reference, click the menu, and choose Modeling > Copy reference. Omni copies the fully-resolved reference (for example, ${@orders_topic.orders.total_revenue}) to your clipboard — paste it directly into your shared measure SQL.The field picker context menu showing Modeling > Copy reference highlighted
Adding a shared measure
topics: [orders_topic, marketing_topic]

shared_dimensions:
  activity_date:
    label: "Activity date"
    mappings:
      orders_topic:
        field: orders.created_at
      marketing_topic:
        field: campaigns.start_date

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
A few important things about shared measures:
  • Each ${@topic.view.field} is already aggregated by the time the shared measure sees it — every topic runs its own subquery first.
  • Any field you reference is auto-included in the right subquery. You don’t need to also add it to the workbook.
  • Filters on a shared measure run after the join. For example, revenue_per_dollar_spent > 1.5 is applied as a WHERE on the joined result in the generated SQL.
  • Write the sql: as plain math, not as a re-aggregation. Combine the per-topic values with arithmetic, CASE, COALESCE, NULLIF, etc.
Write shared measures as plain math, not re-aggregations. Each topic-scoped field is already a single aggregated value by the time the shared measure runs. Wrapping one in SUM(...) or COUNT(...) — or setting aggregate_type: — re-aggregates over the post-join result, which usually isn’t what you want.
5

Save and use the composite topic

Save the file. The composite topic appears in the topic picker for any workbook on the same model — open a workbook, select the composite topic, and mix fields from any of the included topics in a single query.

Next steps