XDM Data Modeling
01 Dec 2024 » Platform
Navigating an Experience Data Model (XDM) schema is not always easy. If your schema is simple, you can probably fit it on a screen and see it in full. However, the moment you start adding nested fields, things can get hairy very quickly. Not only this, but the XDM nomenclature can also feel confusing. The goal of this post is to clarify how to model the data in XDM, using a bottom-up approach: I will start with the most granular elements and how they are grouped to create an XDM schema.
JSON
I am sure you have already noticed that XDM is built on top of JSON Schema, inheriting a similar syntax. This is especially apparent when you use the API, as the Accept
HTTP header usually takes one of these two values:
application/vnd.adobe.xed-id+json
application/vnd.adobe.xed+json
If this is not enough, XDM uses JSON-LD syntax to assign namespaces to fields. I am not an expert in namespaces, I often get confused by them, so I will go any further. If you need to learn more about namespaces, I suggest you review the help page on Namespacing in XDM.
Scalar field types
As with any type of schema or programming language, there must be a fundamental way to represent individual fields. Think of it as the variable types in a strongly typed programming languages. This is an example of how XDM enhances JSON.
XDM defines the following scalar or basic types:
- String
- Number
- Long
- Integer
- Short
- Byte
- Date
- DateTime
- Boolean
If you are not familiar with how computers store and manipulate data, I suggest you first learn it. Otherwise, you will easily get confused with these field types, especially those that store numbers (Number, Long, Short…)
In the documentation, you will also see another scalar type: Enum. This is just a string field that can only have one of a predefined set of values. For example, a color enum could be limited to the most common color names, like “white”, “blue” or “orange”, but would not accept the value “house”.
Since you will have to send data to AEP from other systems, you can check how these XDM scalar types map to types in other formats.
You can also define your custom field types, in case you need it, although you can only do it through the API: Define XDM fields.
Dimensional field types
If all you had were scalar field types, XDM schemas would be unmanageable. Imagine a profile with 100 attributes, all of them in one single list. The idea is to group the attributes in meaningful ways. For example, you would want the contact details of your profile to be grouped together, while the subscription information should be in a different group.
In XDM you have the following dimensional field types:
- Array. This is an unordered list of elements that are all of the same type and have a relationship between them. These elements can be scalars or objects. Be careful with arrays, as there are some limitations with their manipulation and there are guardrails on the cardinality.
- Object. This is a collection of other fields, which can be scalar or dimensional. In other words, an object can hold any number of scalars, maps, arrays, and other objects. Yes, an object can hold other objects. All fields within an object must be named.
- Map. A map is very similar to an object, with the main difference being that an object has a pre-defined structure, while a map has an unknown or variable structure. You can assign any JSON object to a map. I do not recommend XDM maps unless you know what you are doing, as their flexibility makes them difficult to use.
I hope you can see by now how, from basic field types, you can start building complex data structures.
Data types
I have been avoiding the expression “data type” because, in XDM, data type has a specific meaning. Personally, I find this quite confusing, as I have always used data types to denote what XDM refers to as field types.
Data types in XDM are just objects that have been created by Adobe for your convenience. For example, there is a data type called Browser details, to capture information about a browser in a clickstream XDM schema, or a Refund to capture refunded product information.
Using data types is optional, they are just there to make your life easier. If they have what you need, just add them to your XDM schemas. Otherwise, you can just create your custom objects or, if you feel like it, create your custom data types via the corresponding API.
Field groups
One level above the data types we get to the field groups. These are more complex objects, made out of combinations of scalar fields, dimensional fields, and data types.
Let’s illustrate the concept field group with an example, the Work Contact Details field group, which is composed of:
- A Postal address data type named
workAddress
. - An Email address data type named
workEmail
. - A Phone number data type named
workPhone
. - A string array to capture all companies that a person works for.
You might be wondering why there are data types for email addresses and phone numbers, should they not be simple strings? If a string is all you need, then, by all means, create your own data type or field group with simple strings for these fields. However, if you want to capture not only the email address but additional fields like a flag to indicate whether the email address is usable, then a data type makes sense.
This example shows an out-of-the-box (OOTB) field group, which Adobe has already created for you. However, there is no expectation that you use these Adobe-provided field groups. You are more than welcome to create your custom field groups and this is what I have seen in the implementations done by Adobe data architects. However, as opposed to data types, field groups are not optional, you must always create or use existing field groups in your XDM schemas.
AEP also allows you to extend an OOTB field group, by adding a custom field to it. However, I strongly recommend against it. You will get a new field group with a weird name and will not get any future updates to the field group.
Classes
At the pinnacle of the data modeling, we find the classes. There are two main classes:
- XDM Individual Profile. This is the base class for your profile information. You can have multiple profile schemas, although they all refer to the same profile.
- XDM ExperienceEvent. Base class for events. Each event class is independent of other event classes.
I know that there is a third type of class for custom classes. However, I will skip it for today; in my experience, it is rarely used. I may write about them in a future post.
If you have an AEP B2B license, you know of the additional B2B schemas. I have already written a blog post explaining them, just click on the previous link.
Union schema
One common misconception that some people have is that they imagine XDM schemas as equivalent to tables in a relational database. In AEP, all profile schemas are combined into a single, unified schema. I already wrote a post only on the unified profile, which I recommend if you need a refresher.
The reason for having multiple XDM schemas is to accommodate the various datasets that will contribute to the union schema since each dataset will contain a different set of profile attributes.
Summary table
Let’s summarize what I have explained so far in a table, now in reverse order of the explanation above.
Data Model Element | Description |
---|---|
Class |
|
Field Group | Combinations of scalar fields, dimensional fields, and data types OOTB vs custom |
Data Type | Optional, pre-defined XDM objects |
Dimensional fields |
|
Scalar fields |
|
ERD
To finalize this post, I want to spend some time explaining how to document your schemas. The recommended design technique is to use an Entity Relationship Diagram (ERD). Although this type of diagram is usually associated with relational databases, you can use ERDs for whatever you want. See this example from Experience League:
One way you can use it is to show the profile schemas and surround them with event schemas, field groups, and/or data types. Then, show that event schemas have a 1:N relationship with the profile schema(s), while field groups and data types have a 1:1 relationship with the profile unless part of an array.
In the previous example, you can see:
- Main profile schema: Customers.
- Event schemas: ProductCartEvents, CartCheckouts and CartAbandons.
- Field groups and data types: LoyaltyAccounts, Subscriptions, Hotels, Addresses