Add and update array items
Choose a mutation
| Requirement | Mutation |
|---|---|
| Insert or update one stable identity | upsertArrayItem |
| Make the array exactly match a collection | replaceArrayItems |
| Remove every item without replacement | deleteArray |
Insert or update one item with upsertArrayItem
upsertArrayItem addresses an item by customer-owned itemId. It does not require a previous read.
Example: Insert a favorite
mutation UpsertFavorite($input: UpsertArrayItemInput!) {
upsertArrayItem(input: $input) {
acknowledged
insertedCount
matchedCount
modifiedCount
deletedCount
item {
key
value
id
itemId
sortString
sortNumber
sortDate
dateModified
}
}
}
{
"input": {
"scope": "USER",
"key": "content:favorites",
"itemId": "movie:100",
"value": {
"title": "Example Movie",
"mediaType": "MOVIE"
},
"sortString": "Example Movie",
"sortDate": "2026-09-18T10:30:00Z"
}
}
{
"data": {
"upsertArrayItem": {
"acknowledged": true,
"insertedCount": 1,
"matchedCount": 0,
"modifiedCount": 0,
"deletedCount": 0,
"item": {
"key": "content:favorites",
"value": {
"title": "Example Movie",
"mediaType": "MOVIE"
},
"id": "66b100000000000000000001",
"itemId": "movie:100",
"sortString": "Example Movie",
"sortNumber": null,
"sortDate": "2026-09-18T10:30:00.000Z",
"dateModified": "2026-09-18T10:31:12.000Z"
}
}
}
}
The service-generated id is distinct from the customer-owned itemId.
Example: Update the same favorite
Use the same itemId with the changed value:
{
"input": {
"scope": "USER",
"key": "content:favorites",
"itemId": "movie:100",
"value": {
"title": "Example Movie (4K)",
"mediaType": "MOVIE"
}
}
}
A normal update retains the service-generated id and advances dateModified. Typical counts are insertedCount: 0 and matchedCount: 1. modifiedCount is database-reported; do not use it as a generic success flag. acknowledged and the returned item describe the accepted result.
Updating sort fields
For an existing item:
| Input state | Behavior |
|---|---|
| Field omitted | Preserve the stored value |
Explicit null | Remove the stored value |
| Non-null value | Set or replace the value |
For example, omit sortString, change sortNumber, and clear sortDate:
{
"input": {
"scope": "USER",
"key": "content:favorites",
"itemId": "movie:100",
"value": {
"title": "Example Movie",
"mediaType": "MOVIE"
},
"sortNumber": 100,
"sortDate": null
}
}
Legacy-item convergence
When a qualifying legacy item matches the requested identity, upsert writes the explicit stored itemId, retains one survivor, and removes matching duplicates. deletedCount reports duplicates removed. Reads alone never perform this migration.
Replace an array with replaceArrayItems
replaceArrayItems atomically replaces every item under a scope and key. Every supplied item must have a unique itemId.
Example: Replace the favorites array
mutation ReplaceFavorites($input: ReplaceArrayItemsInput!) {
replaceArrayItems(input: $input) {
acknowledged
items {
key
value
id
itemId
sortString
sortNumber
sortDate
dateModified
}
}
}
{
"input": {
"scope": "USER",
"key": "content:favorites",
"items": [
{
"itemId": "movie:100",
"value": {
"title": "Example Movie",
"mediaType": "MOVIE"
},
"sortString": "Example Movie",
"sortNumber": 100,
"sortDate": "2026-09-18T10:30:00Z"
},
{
"itemId": "movie:200",
"value": {
"title": "Another Movie",
"mediaType": "MOVIE"
},
"sortString": "Another Movie",
"sortNumber": 200
}
]
}
}
{
"data": {
"replaceArrayItems": {
"acknowledged": true,
"items": [
{
"key": "content:favorites",
"value": {
"title": "Example Movie",
"mediaType": "MOVIE"
},
"id": "66b100000000000000000001",
"itemId": "movie:100",
"sortString": "Example Movie",
"sortNumber": 100,
"sortDate": "2026-09-18T10:30:00.000Z",
"dateModified": "2026-09-18T10:31:12.000Z"
},
{
"key": "content:favorites",
"value": {
"title": "Another Movie",
"mediaType": "MOVIE"
},
"id": "66b100000000000000000002",
"itemId": "movie:200",
"sortString": "Another Movie",
"sortNumber": 200,
"sortDate": null,
"dateModified": "2026-09-18T10:31:12.000Z"
}
]
}
}
}
Replacement behavior
- Replacement is atomic.
- Previous items omitted from the request are removed.
- Every supplied item is recreated, so service-generated IDs change.
- Returned items preserve input order.
- Values do not need a matching
value.id. itemsmust be non-empty.- Request
itemIdvalues must be unique.
Clearing an array
replaceArrayItems(items: []) is invalid. Use deleteArray to clear an array.
Atomicity and concurrent writes
A failed replacement leaves the previous array unchanged. An unrecoverable transaction conflict returns CONCURRENT_WRITE_CONFLICT; stored data remains unchanged.
Validation summary
- Invalid key or
itemId:IDENTIFIER_CONSTRAINT - Empty replacement:
EMPTY_ARRAY - Duplicate request identity:
DUPLICATE_ITEM_ID - Invalid date:
DATETIME_CONSTRAINT
See Errors and limits.