Using OJAI Mutation Syntax
To perform updates using OJAI, you specify the document you want to update using its
_id field, create mutations for that document, and then update it in
your document store. OJAI defines a syntax for specifying mutations. Mutations allow you to
append, decrement, delete, increment, combine, replace, and update fields in a document. This
topic describes the syntax for the supported mutation operations and provides
examples.
The following table lists the mutations OJAI supports. Each entry in the table contains a brief description of the mutation and a link to a section in this topic that describes the mutation in more detail.
| Mutation Operation | Description |
|---|---|
| Append | Appends values to binary, string, and array fields |
| Decrement | Decrements field values |
| Delete | Deletes fields |
| Increment | Increments field values |
| Merge | Combines a nested document with an existing document |
| Put | Replaces field values or adds new fields |
| Set | Updates field values or adds new fields |
The examples in this topic use the following sample JSON document:
{
"_id" : "id1",
"a" : {
"b" : [ { "boolean" : false }, { "decimal" : 123.456 } ],
"c" : {
"d" : 10,
"e" : "Hello"
}
},
"m" : "MapR wins"
}
OJAI Append Mutations
- Syntax
-
{"$append":{"fieldpath":value}}{"$append":[{"fieldpath1":value1},{"fieldpath2":value2},...]} - Description
-
The
$appendmutation is a read-modify-write operation. Use it to append specified values to existing binary, string, or array type fields. If there is type mismatch in any intermediate field specified in a fieldpath for the document, the mutation fails with an error. For example, an append mutation on field patha.b.cfails if the fieldais a scalar.To append multiple field paths, use an array notation to list the field paths.
- Example
-
The following mutation appends an element to the array
a.band appends the string" MapR"to the end of the string already in the field patha.c.e:{"$append":[{"a.b":{"appd":1}},{"a.c.e":" MapR"}]}The mutation results in the following document, with the field updates highlighted in bold:
{ "_id" : "id1", "a" : { "b" : [ { "boolean" : false }, { "decimal" : 123.456 }, { "appd" : 1 } ], "c" : { "d" : 10, "e" : "Hello MapR" } }, "m" : "MapR wins" }
OJAI Decrement Mutations
- Syntax
-
{"$decrement":"fieldpath"}{"$decrement":{"fieldpath":decrementValue}}{"$decrement":[{"fieldpath1":decrementValue1},{"fieldpath2":decrementValue2},...]} - Description
-
The
$decrementmutation decrements the value in the fieldpath. To decrement multiple field paths, use an array notation to list the field paths.If the fieldpath does not exist, the mutation adds a new field to the document with the value decrementValue.
The decrementValue is optional and defaults to -1.
The mutation fails if there is a type mismatch in the field.
- Example
-
The following updates the value 10 in
a.c.dto 5 by using the decrement mutation:{"$decrement":{"a.c.d":5}}The mutation results in the following document, with the field update highlighted in bold:
{ "_id" : "id1", "a" : { "b" : [ { "boolean" : false }, { "decimal" : 123.456 } ], "c" : { "d" : 5, "e" : "Hello" } }, "m" : "MapR wins" }
OJAI Delete Mutations
- Syntax
-
{"$delete":"fieldpath"}{"$delete":["fieldpath1","fieldpath2",...]} - Description
-
The
$deletemutation removes either a single field or a list of fields from a document. If the field does not exist, the delete ignores that field. - Example
-
The following mutation removes two fields from the document:
{"$delete":["a.b[1]","a.c.e"]}The mutation results in the following document:
{ "_id" : "id1", "a" : { "b" : [ { "boolean" : false } ], "c" : { "d" : 10 } }, "m" : "MapR wins" }
OJAI Increment Mutations
- Syntax
-
{"$increment":"fieldpath"}{"$increment":{"fieldpath":incrementValue}}{"$increment":[{"fieldpath1":incrementValue1},{"fieldpath2":decrementValue2},...]} - Description
-
The
$incrementmutation increments the value in the fieldpath. To increment multiple field paths, use an array notation to list the field paths.If the fieldpath does not exist, the mutation adds a new field to the document with the value incrementValue.
The incrementValue is optional and defaults to 1.
The mutation fails if there is a type mismatch in the field.
- Example
-
The following updates the value 10 in
a.c.dto 15 by using the increment mutation:{"$increment":{"a.c.d":5}}The mutation results in the following document, with the field update highlighted in bold:
{ "_id" : "id1", "a" : { "b" : [ { "boolean" : false }, { "decimal" : 123.456 } ], "c" : { "d" : 15, "e" : "Hello" } }, "m" : "MapR wins" }
OJAI Merge Mutations
- Syntax
-
{"$merge":{"fieldpath":nestedDocument}} - Description
-
The
$mergemutation combines a nestedDocument with an existing document at a specified fieldpath. If the original document already contains subfields specified in the nestedDocument, then the mutation replaces the values for those subfields. Otherwise, it adds new subfields to the document.NOTEThe$mergemutation does not support the array notation that other mutation operations provide.To specify more than one merge operation in a single mutation, use the syntax described at either Specifying Multiple Mutation Operations or OJAI Mutations Without Explicit Mutation Operation Names. When using these syntax variations, avoid specifying overlapping field paths. HPE Data Fabric Database treats these as conflicting mutations and discards conflicts.
- Examples
-
The following mutation replaces the pre-existing field path
a.c.dwith the value 11. It adds a new subfieldyto the nested documenta.c.{"$merge":{"a.c":{"d":11,"y":"yo"}}}The mutation results in the following document, with the field updates highlighted in bold:
{ "_id" : "id1", "a" : { "b" : [ { "boolean" : false }, { "decimal" : 123.456 } ], "c" : { "d" : 11, "e" : "Hello", "y" : "yo" } }, "m" : "MapR wins" }The following mutation replaces the value in the field path
a.band adds a new subfielda.d:{"$merge":{"a":{"b":1,"d":"MapR"}}}The mutation results in the following document, with the field updates highlighted in bold:
{ "_id" : "id1", "a" : { "b" : 1, "c" : { "d" : 10, "e" : "Hello" }, "d" : "MapR" }, "m" : "MapR wins" }
OJAI Put Mutations
- Syntax
-
{"$put":{"fieldpath":value}}{"$put":[{"fieldpath1":value1},{"fieldpath2":value2},...]} - Description
-
The
$putmutation is a replace operation. It is not a read-modify-write operation; it does no validation on the data. If the specified fieldpath exists, the mutation replaces the fieldpath's value with the new value, regardless of the type of the original value. For example, you can update a fielda.bfrom an array to a nested document. If the fieldpath does not exist, the mutation creates a new field with the given value. Because the operation does no data validation, it is significantly faster than the set operation.To replace multiple field paths, use an array notation to list the field paths.
- Example
-
The following example replaces the pre-existing fields
a.banda.c.dwith values whose types differ from the original types. It also adds a new fielda.x.{"$put":[{"a.b":{"boolean":true}},{"a.c.d":"eureka"},{"a.x":1}]}The mutation results in the following document, with the field updates highlighted in bold:
{ "_id" : "id1", "a" : { "b" : { "boolean" : true }, "c" : { "d" : "eureka", "e" : "Hello" }, "x" : 1 }, "m" : "MapR wins" }The mutation behaves as follows for the pre-existing fields:
- For
a.b, the mutation replaces the original array of nested documents with a single nested document. - For
a.c.d, the mutation changes the field from an integer to a string.
- For
OJAI Set Mutations
- Syntax
-
{"$set":{"fieldpath":value}}{"$set":[{"fieldpath1":value1},{"fieldpath2":value2},...]} - Description
-
The
$setmutation updates one or more fields in a document. It is a read-modify-write operation. It validates the type of the existing value before applying the mutation. If the specified fieldpath does not exist in a document, the mutation creates a new field. If the fieldpath exists but is not of the same type as the type of new value, then the entire mutation fails.To update multiple field paths, use an array notation to list the field paths.
- Example
-
The following example updates the pre-existing fields
a.b.[0]anda.c.d. It also adds a new fielda.x.{"$set":[{"a.b[0].boolean":true},{"a.c.d":11},{"a.x":1}]}The mutation results in the following document, with the field updates highlighted in bold:
{ "_id" : "id1", "a" : { "b" : [ { "boolean" : true }, { "decimal" : 123.456 } ], "c" : { "d" : 11, "e" : "Hello" }, "x" : 1 }, "m" : "MapR wins" }
Specifying Multiple Mutation Operations
You can specify more than one operation in a single mutation by specifying each operation separated by a comma.
The following is a mutation with six operations:
{
"$set":{"x":[1,2,3]},
"$put":{"a.c.e":{"$binary":"AAAADg=="}},
"$increment":"a.b[1].decimal",
"$delete":"a.b[0]",
"$merge":{"newDoc":{"k":"MapR DBShell rocks!!"}},
"$append":{"m":"!!!"}
}
It results in the following document, with the field updates highlighted in bold:
{
"_id" : "id1",
"a" : {
"b" : [ { "decimal" : 124.456 } ],
"c" : {
"d" : 10,
"e" : { "$binary" : "AAAADg==" }
}
},
"m" : "MapR wins!!!",
"newDoc" : { "k" : "MapR DBShell rocks!!" },
"x" : [ 1, 2, 3 ]
}
The mutation applies the updates in the following manner:
- The
$setmutation adds a new array fieldxwith the value[1, 2, 3]. - The
$putmutation replaces the string"Hello"with the nested document{"$binary":"AAAADg=="}. - The
$incrementmutation increments the value123.456in the second element of the arraya.b. - The
$deletemutation deletes the field patha.b[0], resulting in a single element arraya.b. - The
$mergemutation adds a new fieldnewDocwith the nested document{"k":"MapR DBShell rocks!!"}as its value. - The
$appendmutation appends the string"!!!"to the end of the string"MapR wins".
When you specify a mutation with field paths that are overlapping, HPE Data Fabric Database detects the conflict, discards the previous conflicting operation, and proceeds with the next operation.
{"_id":"id1", "a":{"b":{"c":5}}}a.b:{"$delete":"a.b","$set":{"a.b.d":10}}a.b and then to
replace it with a.b.d as follows:
{"_id":"id1", "a":{"b":{"d":"10"}}}{"_id":"id1", "a":{"b":{"c":5,"d":"10"}}}In
this case, the set operation on a.b.d causes the delete operation
on a.b to be discarded.
$increment and $delete operations are not
conflicting because one operates on a.b[1], while the other operates on
a.b[0]. On the other hand, the following are conflicting
operations:{"$increment":"a.b[1].decimal","$delete":"a.b"}OJAI Mutations Without Explicit Mutation Operation Names
You can specify a mutation without using an explicit mutation name. These mutations run as merge operations.
For example, the following mutation merges the fields k and
a.c.d to the document by adding a new field k and
updating a.c.d:
{"k":"eureka","a":{"c":{"d":1234}}}
The mutation results in the following document, with updates highlighted in bold:
{
"_id" : "id1",
"a" : {
"b" : [ { "boolean" : false }, { "decimal" : 123.456 } ],
"c" : {
"d" : 1234,
"e" : "Hello"
}
},
"k" : "eureka",
"m" : "MapR wins"
}