← Back to list

Customer Journey Analytics Data Views Are Effectively a Semantic Layer

Adobe never uses the term. But once you look past the naming, a CJA Data View does almost exactly what dbt Semantic Layer, Cube, or LookML…

Albin Issac in Tech Learnings · 2026-07-24 18:54 · 0 claps · 12.3 min read
#data-engineering #data-analysis #web-development #semantic-layer #digital-marketing
Open on Medium ↗
Wiki topics: ECO · Economy · General DIG · Digital Marketing GRW · Growth & Analytics 🌐 · Web Development 🔧 · Data Engineering

Customer Journey Analytics Data Views Are Effectively a Semantic Layer

Adobe never uses the term. But once you look past the naming, a CJA Data View does almost exactly what dbt Semantic Layer, Cube, or LookML are trying to do — with a genuinely surprising escape hatch for proving it.

Disclaimer: The views and opinions expressed in this article are my own personal perspective. They do not represent the views, positions, or strategies of my employer or any organization I am affiliated with.

Who this is for: CJA implementers and architects, plus anyone from the modern-data-stack world (dbt, Cube, Looker) curious how the Adobe side handles the same problem.

If you’ve spent time in the modern data stack, “semantic layer” means something specific: define a metric once, in one governed place, and let every tool downstream — a dashboard, a spreadsheet, an AI agent — read the same definition instead of reinventing it. dbt Semantic Layer, Cube, LookML, AtScale: different implementations, same pitch.

Adobe never markets Customer Journey Analytics Data Views this way. In the docs they’re just “a curated lens on top of your dataset.” A Data View decouples raw schema from consumption, applies governed business definitions on top, and — this is the part that earns the comparison — can be queried by SQL tools outside Adobe entirely, through something called the BI Extension. That last piece is what turns “reporting layer” into “semantic layer,” and it’s worth walking through properly.

The one-sentence version

A CJA Data View takes a raw AEP dataset in, applies one governed set of metrics and dimensions, and every consumption surface after that — Analysis Workspace, an API, an external BI tool, a scheduled cloud export, or an AI agent — reads the same definition.

What actually lives inside a Data View

Strip away the marketing and a Data View is a configuration object sitting on top of one or more AEP datasets, doing a lot more than “pick some dimensions”:

  • Schema-to-component mapping — raw XDM schema fields become dimensions or metrics (most fields can go either way), with up to 5,000 of each per Data View. A single Data View can also blend multiple datasets together, as long as the schemas are compatible — web, app, and CRM data feeding one governed view.
  • Component settings — friendly names, descriptions, context labels, tags, formatting, and Hide Component in Reporting all apply to metrics and dimensions alike, on a per-Data-View basis. A deeper layer splits by component type: Attribution is metrics-only, while Persistence (allocation + expiration), Include/Exclude Values, Substring/Delimiter parsing, and Summary Data Group linking are all dimensions-only.
  • Standard components — every Data View auto-includes a baseline set (Events, People, Sessions metrics; Minute/Hour/Day/Week/Quarter/Year dimensions) so you’re never starting from zero.
  • Calculated metrics and derived fields — formula-based measures and multi-field derived dimensions, scoped to that Data View.
  • Shared metrics and dimensions — managed in their own dedicated screen, not just built once and copied — define once, reuse across multiple Data Views. The closest thing CJA has to a central metrics dictionary.
  • Global filters — built from Segments (what Adobe Analytics used to just call Filters): reusable, saved audience/session/event definitions built from the Data View’s own components, so one can’t reference a field the view doesn’t expose. But from the Data View’s own configuration surface, a segment itself isn’t a setting — the only thing that actually happens in its Settings tab is dragging one in as a Global Filter, e.g. restricting the whole view to a single website domain so a multi-brand org can give each site its own scoped view off one shared dataset. Once it’s there, every report from that Data View inherits it automatically, with no opt-out inside Workspace.
  • Container settings — rename the Person, Session, and Event containers to match your org’s own language (Person → Customer, Session → Visit, Event → Hits), set in the Data View’s Configure tab. These names propagate everywhere containers show up, segments included.
  • Session settings — what actually counts as a “session” is itself configurable per Data View: a timeout duration (minutes up to weeks), a specific metric that triggers a new session boundary (an app-launch event, say), or even a segment-based definition. Non-destructive, so two Data Views can define “session” differently over identical underlying data. (Identity stitching — how Person IDs resolve across devices — sits one level up, at the Connection a Data View is built on, not in the Data View itself.)
  • Time and calendar settings — time zone, fiscal vs. standard calendar, first day of week — can differ from one Data View to the next against the same underlying data.
  • Governance and access — create, edit, copy, delete, export to CSV, and — critically — Product Profile access control per Data View, which is how CJA hands one team a curated view and another team a completely different one off the same source data.

None of that is exotic on its own. What makes it a semantic layer rather than just “report configuration” is what happens once it’s defined — the same underlying data can feed completely different, independently governed audiences without ever duplicating itself.

Figure: One AEP dataset, one governed Data View, five consumption surfaces — plus the ungoverned bypass most teams don’t realize exists.

Figure: One AEP dataset, one governed Data View, five consumption surfaces — plus the ungoverned bypass most teams don’t realize exists.

BI Extension

Here’s the detail that settles the argument, and it’s also the one people get wrong most often: CJA does not have its own query engine. The SQL engine is Adobe Experience Platform’s Query Service, which sits underneath the whole platform and gives SQL access to the raw data lake. CJA’s own contribution is the BI Extension — a layer that rides on top of Query Service and exposes Data Views, not raw datasets, as queryable tables over the standard PostgreSQL wire protocol.

That distinction shows up directly in how you connect. Query Service databases follow a {sandbox}:all naming pattern — raw datasets in that sandbox, governed the normal AEP way (roles, permissions, labels). The BI Extension instead gives you {sandbox}:cja — only the Data Views you've been granted, as tables, with the same renamed fields and calculated metrics an analyst sees in Analysis Workspace. Point a BI tool's PostgreSQL connector at the right credentials, select prod:cja as the database, and your Data Views show up in the navigator like any other table.

That’s the semantic-layer property that matters: the BI Extension deliberately exposes the modeled layer, not the lake. A report built this way is reading the exact same metric definition as the Workspace analyst sitting next to it — not a parallel reimplementation of “sessions” that quietly drifts out of sync over time.

The BI Extension doesn’t expose your data lake. It exposes your Data Views — which means external BI tools inherit the same governed definitions your analysts already use, instead of reinventing them.

Who’s actually on the supported list

This is worth clearing up, because it’s easy to assume this is a Power BI/Tableau-only feature — it isn’t. Adobe currently tests and officially supports five clients: Power BI, Tableau Desktop, Looker, Jupyter Notebook, and RStudio. That last pair matters more than it sounds — it means a data scientist can pull governed Data View output straight into a pandas or R dataframe, not just a dashboard. Beyond that named list, any tool that speaks the PostgreSQL wire protocol can probably connect too — the documentation hedges carefully here: other PSQL-compatible tools “might work as well, but are not yet supported officially.” Treat that as “works, at your own risk,” not “won’t work.”

The catch

This capability is gated harder than the pitch suggests. Access itself comes from a specific Product Profile permission — “Data View Tools: CJA BI Extension” — on top of requiring the Select package or higher; Basic doesn’t get SQL access at all. On Select, queries are ad hoc only: a 10-minute execution timeout, and a row limit that defaults to a startling 50 rows — you have to explicitly add LIMIT n to get more, up to a 50,000-row ceiling.

There are shape limits on the query itself too, and Adobe is blunt about the main one: “The BI extension requires aggregate queries. You can’t use SQL like `SELECT FROM ...to get the raw, underlying rows."* Every query needs aSUM,COUNT, orDISTINCT— there's no row-level export path here at all. And there's a sharper edge that only shows up once you actually try it: nested XDM field groups — Web, Device, Environment, anything holding an actual page URL or domain — don't resolve to usable columns unless you connect with aFLATTEN` parameter appended to the connection string, and that only works from a third-party client. The native Query Service UI, meanwhile, can't flatten anything at all, which means some of the most commonly requested marketing dimensions are effectively invisible until someone knows to ask for them this specific way.

Concretely: without FLATTEN, a nested field like the Web field group shows up as a single opaque column — SELECT "web" FROM ... returns one blob of text per row, not a usable dimension. Reconnect with the parameter appended to the database name, and it explodes into real, queryable columns instead:

-- Test it directly with psql — same credentials as Power BI/Tableau,
-- just appended to the database name
psql "host=<query-service-host> port=80 dbname=prod:cja?FLATTEN user=<username> sslmode=require"

-- Now the nested field is queryable directly
SELECT
    "web.webPageDetails.server" AS domain,
    SUM("visits") AS visits
FROM "your_data_view"
GROUP BY "web.webPageDetails.server"
ORDER BY visits DESC;

That single connection parameter is the difference between “domain” being unreachable and being a normal GROUP BY column — don't assume a governed Data View hands you everything Workspace shows you by default.

Ad hoc queries like these never write anything back into the AEP data lake, and that distinction turns out to matter: Adobe’s “no scheduling” restriction on Select is about its own server-side batch queries, not about whether a connected BI tool can refresh itself. A Power BI or Tableau dataset’s nightly scheduled refresh is just the tool re-running the same ad hoc query on its own timer — that works fine on Select, as long as each individual pull still fits inside the 50,000-row, 10-minute ad hoc ceiling. Data Distiller only becomes necessary for pulls bigger than that ceiling, or for scheduling batch queries that write transformed results back into the data lake — not simply because a dashboard happens to refresh on a schedule. And the BI tool itself still needs its own license — Power BI Pro, Tableau Creator, whatever your vendor requires — separate from anything Adobe charges.

Data Insights Agent

There’s a second proof point that didn’t exist when semantic layers were first being pitched: an AI agent grounded in the exact same Data View. CJA’s Data Insights Agent — the generative-AI conversational tool inside the AI Assistant — answers natural-language questions and builds visualizations in Analysis Workspace using components from your Data View, not a freeform read of the underlying dataset. Ask it something in plain English and it’s reasoning over the same dimensions, metrics, and segments an analyst would pick from manually — it can’t invent a field the Data View doesn’t expose.

That’s precisely the argument Cube and other semantic-layer vendors make for why a governed layer matters more now than it used to: an AI agent without one will happily hallucinate a metric definition; an AI agent grounded in one inherits the same governance humans already agreed to.

The catch, again

Access isn’t automatic, and it’s gated at two different layers. At the org level, it needs two Admin Console permissions — “AI Assistant: Product Knowledge” and “Data Insights Agent” under Data View Tools. At the Data View level, each one has to be individually switched on too: an AI Settings section in the Data View’s own Configure tab — the same tab where Container and Session settings live — with an “Enable for Data Insights Agent” toggle, capped at 50 Data Views per organization. And there’s a licensing wrinkle worth knowing before you plan around it: Adobe’s own documentation states free/included access ran through February 28, 2026. Past that date, continued use requires licensing Adobe Experience Platform Agent Orchestrator separately. If you’re reading this after that date, assume you need to check with your Adobe rep before building a workflow around it.

Full Table Export

There’s a third way data leaves a Data View, and it’s built for volume instead of live access. You create it from a freeform table: right-click its header in Analysis Workspace, choose Export full table, and send it to a cloud destination — Amazon S3, Azure (SAS or RBAC), Google Cloud Platform, Snowflake, or AEP’s own Data Landing Zone — once, or on a recurring schedule: daily, weekly, monthly, yearly. Once it exists, it stops being tied to that table: every export, however it was created, shows up centrally under Components > Exports, where it can be edited, rescheduled, or monitored on its own.

The scale difference from BI Extension is the whole point. BI Extension caps out at 50,000 rows per ad hoc pull. Full Table Export scales to 3 million, 30 million, 150 million, or 300 million rows depending on license tier — built for bulk delivery into a warehouse or lake, not interactive querying.

And it still runs through the same governed layer. The export pulls from a specific Data View’s components — calculated metrics, filters, attribution, derived fields, all included — capped at 10 dimensions and 10 metrics per table, output as CSV, JSON, or Parquet. It even inherits the same access control the governance piece covered: a component an admin has restricted from export via a Data Governance label simply can’t be added to the table, full stop.

The catch

Two real constraints worth knowing before building a pipeline around this: calculated metrics using median, percentile, quartile, standard deviation, or regression-style functions aren’t supported in export — Workspace can display them, the export can’t carry them. And Parquet output sanitizes component names on the way out, replacing spaces, commas, colons, and a handful of other characters with underscores.

Where the analogy holds — and where it doesn’t

Stack this against the tools people actually mean when they say “semantic layer” and the picture gets more honest:

  • dbt Semantic Layer defines metrics in version-controlled YAML inside a dbt project and serves them through dbt Cloud’s API. Git history, code review, diffable definitions — CJA Data Views have none of that. Editing one is a UI operation with no version control.
  • Cube runs as an independent server in front of the warehouse, serving metrics over SQL, REST, and GraphQL to any consumer, dbt-optional. CJA’s BI Extension serves SQL only, to a fixed list of five certified clients, and only once you’re licensed for it.
  • LookML is the closest cousin architecturally — a modeling layer tightly bound to one product (Looker, in that case) — which is exactly CJA’s position: powerful, but Adobe-native by design, not tool-agnostic.

So the fair claim isn’t “CJA has a semantic layer like Cube’s.” It’s narrower and still true: CJA Data Views implement the core idea — decouple storage from consumption, define once, govern centrally — without the version control, multi-interface serving, or tool-agnosticism that the dedicated semantic-layer products built their reputation on.

A concrete example

Say one AEP dataset holds both web analytics events and product-usage telemetry. Marketing wants funnel and channel metrics; the product team wants feature adoption cut by device and account tier. Instead of duplicating the dataset or building two disconnected pipelines, you build two Data Views on the same source: one with marketing-friendly component names and a global filter excluding internal test traffic, the other with product-specific calculated metrics and no such filter. Same underlying data, two governed lenses, each Product Profile pointed at the one it should see.

Neither team touches raw schema fields. Neither team can accidentally see the other’s calculated metrics. That’s the “define once, consume differently” pattern in practice — not a hypothetical, just what Data Views are for.

Key takeaways

  • A Data View decouples raw AEP schema from what analysts and tools actually consume — the core semantic-layer move.
  • Shared metrics/dimensions and Global Filters (segments pinned into the Data View’s own settings) are the closest things CJA has to centralized metric governance.
  • The BI Extension is the strongest evidence for the claim: it exposes Data Views, not raw datasets, to external BI tools over SQL.
  • Data Insights Agent extends the same governance to AI: it answers questions using the Data View’s components, not a freeform read of the dataset.
  • Full Table Export extends it to bulk delivery: up to 300 million rows to S3, Azure, GCP, Snowflake, or Data Landing Zone, still built from the Data View’s governed components and still subject to Data Governance export restrictions.
  • CJA doesn’t have its own query engine — it rides on AEP Query Service, distinguished by the :cja vs :all database scope.
  • The honest caveat: no version control, no multi-interface serving, a five-client certified list (Power BI, Tableau, Looker, Jupyter, RStudio), aggregated-only data with a 50-row default, nested fields needing a FLATTEN connection parameter, and Data Distiller required only for bigger pulls or Adobe-side scheduled batch jobs — not just because a dashboard refreshes nightly.

Call it what it is: a semantic layer with an Adobe accent — the same idea the modern data stack keeps re-inventing, minus the git history.

Related reading

References & further reading


메타데이터
post_id
2d60e7f04420
slug
customer-journey-analytics-data-views-are-effectively-a-semantic-layer-2d60e7f04420
url
https://medium.com/tech-learnings/customer-journey-analytics-data-views-are-effectively-a-semantic-layer-2d60e7f04420
canonical_url
https://medium.com/tech-learnings/customer-journey-analytics-data-views-are-effectively-a-semantic-layer-2d60e7f04420
author_url
https://medium.com/@techforum
status
ok
fetched_at
2026-09-03 18:34:02