You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -86,7 +86,7 @@ Entity Updates (ready for epilot)
86
86
-**`events`**: Object with event names as keys
87
87
-**`entities`**: Array of entity configurations for each event
88
88
-**`entity_schema`**: The epilot entity schema (e.g., "contact", "contract", "billing_account", see [Core Entities](https://docs.epilot.io/docs/entities/core-entities/))
89
-
-**`unique_ids`**: Array of attribute names that uniquely identify this entity
89
+
-**`unique_ids`**: Array of unique identifier configurations (see [Repeatable Field Types as Unique Identifiers](#repeatable-field-types-as-unique-identifiers))
90
90
-**`jsonataExpression`**: Optional JSONata expression to pre-process the event data
91
91
-**`enabled`**: Optional boolean or JSONata expression to conditionally enable/disable entity processing (defaults to `true`)
92
92
-**`fields`**: Array of field mappings
@@ -206,6 +206,229 @@ Set a fixed value regardless of input data. Useful for setting tags, purposes, e
206
206
}
207
207
```
208
208
209
+
## Repeatable Field Types as Unique Identifiers
210
+
211
+
Some entity fields in epilot are repeatable fields stored as arrays of objects. The most common examples are **email** and **phone** fields:
212
+
213
+
```json
214
+
{
215
+
"email": [{ "email": "user@example.com" }],
216
+
"phone": [{ "phone": "+49123456789" }]
217
+
}
218
+
```
219
+
220
+
When using these fields as unique identifiers, special handling is required because:
221
+
1.**Search**: The Elasticsearch filter must use the nested path (e.g., `email.email.keyword` instead of `email.keyword`)
222
+
2.**Create/Update**: Values must be transformed to the repeatable format when creating or updating entities
223
+
224
+
### Configuration
225
+
226
+
To use a repeatable field type as a unique identifier, add the `_type` hint to the **field definition** in the `fields` array:
227
+
228
+
**Standard field (no _type needed):**
229
+
```json
230
+
{
231
+
"entity_schema": "contact",
232
+
"unique_ids": ["customer_number"],
233
+
"fields": [
234
+
{
235
+
"attribute": "customer_number",
236
+
"field": "customerId"
237
+
}
238
+
]
239
+
}
240
+
```
241
+
242
+
**Repeatable field with _type hint:**
243
+
```json
244
+
{
245
+
"entity_schema": "contact",
246
+
"unique_ids": ["email"],
247
+
"fields": [
248
+
{
249
+
"attribute": "email",
250
+
"field": "Email",
251
+
"_type": "email"
252
+
}
253
+
]
254
+
}
255
+
```
256
+
257
+
**Mixed unique identifiers:**
258
+
```json
259
+
{
260
+
"entity_schema": "contact",
261
+
"unique_ids": ["customer_number", "email"],
262
+
"fields": [
263
+
{
264
+
"attribute": "customer_number",
265
+
"field": "customerId"
266
+
},
267
+
{
268
+
"attribute": "email",
269
+
"field": "Email",
270
+
"_type": "email"
271
+
}
272
+
]
273
+
}
274
+
```
275
+
276
+
### Supported Types
277
+
278
+
| Type | Storage Format | Search Path | Use Case |
1.**Search**: System searches for existing contact using `email.email.keyword: "anna.schmidt@example.com"`
330
+
2.**Create**: If not found, creates new contact with email as `[{ "email": "anna.schmidt@example.com" }]`
331
+
3.**Update**: If found, patches the existing contact
332
+
333
+
### Using in Relations
334
+
335
+
Repeatable field types can also be used in relation unique identifiers using the `_type` property:
336
+
337
+
```json
338
+
{
339
+
"attribute": "primary_contact",
340
+
"relations": {
341
+
"operation": "_set",
342
+
"items": [
343
+
{
344
+
"entity_schema": "contact",
345
+
"unique_ids": [
346
+
{
347
+
"attribute": "email",
348
+
"_type": "email",
349
+
"field": "contactEmail"
350
+
}
351
+
]
352
+
}
353
+
]
354
+
}
355
+
}
356
+
```
357
+
358
+
This allows you to look up related entities by their email address, using the correct search path for the email field.
359
+
360
+
### Backward Compatibility
361
+
362
+
Existing configurations without `_type` hints continue to work unchanged. The `_type` hint is only needed for repeatable fields like `email` and `phone`.
363
+
364
+
### Direct Entity Lookup with `_id`
365
+
366
+
When using `_id` as the **only** unique identifier, the system performs an optimized direct entity lookup instead of an Elasticsearch search. This is useful for:
367
+
- Linking to entities where you already know the exact entity ID
368
+
- Performance-critical scenarios where you want to avoid search latency
369
+
- Post-action callbacks where entity IDs are already resolved
0 commit comments