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"
}
{"$append":{"fieldpath":value}}
{"$append":[{"fieldpath1":value1},{"fieldpath2":value2},...]}
The $append mutation 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
path a.b.c fails if the field a is a scalar.
To append multiple field paths, use an array notation to list the field paths.
The following mutation appends an element to the array a.b and
appends the string " MapR" to the end of the string already in the
field path a.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"
}
{"$decrement":"fieldpath"}
{"$decrement":{"fieldpath":decrementValue}}
{"$decrement":[{"fieldpath1":decrementValue1},{"fieldpath2":decrementValue2},...]}
The $decrement mutation 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.
The following updates the value 10 in a.c.d to 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"
}
{"$delete":"fieldpath"}
{"$delete":["fieldpath1","fieldpath2",...]}
The $delete mutation removes either a single field or a list of
fields from a document. If the field does not exist, the delete ignores that field.
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"
}
{"$increment":"fieldpath"}
{"$increment":{"fieldpath":incrementValue}}
{"$increment":[{"fieldpath1":incrementValue1},{"fieldpath2":decrementValue2},...]}
The $increment mutation 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.
The following updates the value 10 in a.c.d to 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"
}
{"$merge":{"fieldpath":nestedDocument}}
The $merge mutation 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.
$merge mutation 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 Ezmeral Data Fabric Database treats these as conflicting mutations and discards conflicts.
The following mutation replaces the pre-existing field path a.c.d
with the value 11. It adds a new subfield y to the nested document
a.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.b and
adds a new subfield a.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"
}
{"$put":{"fieldpath":value}}
{"$put":[{"fieldpath1":value1},{"fieldpath2":value2},...]}
The $put mutation 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 field a.b from 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.
The following example replaces the pre-existing fields a.b and
a.c.d with values whose types differ from the original types. It
also adds a new field a.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:
a.b, the mutation replaces the original array of nested
documents with a single nested document.a.c.d, the mutation changes the field from an integer to a
string.{"$set":{"fieldpath":value}}
{"$set":[{"fieldpath1":value1},{"fieldpath2":value2},...]}
The $set mutation 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.
The following example updates the pre-existing fields a.b.[0] and
a.c.d. It also adds a new field a.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"
}
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:
$set mutation adds a new array field x with the
value [1, 2, 3].$put mutation replaces the string "Hello" with the
nested document {"$binary":"AAAADg=="}.$increment mutation increments the value 123.456
in the second element of the array a.b.$delete mutation deletes the field path a.b[0],
resulting in a single element array a.b.$merge mutation adds a new field newDoc with the
nested document {"k":"MapR DBShell rocks!!"} as its value.$append mutation appends the string "!!!" to the
end of the string "MapR wins".When you specify a mutation with field paths that are overlapping, HPE Ezmeral 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"}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"
}