Hi @mickaelhemri,
AsyncBucket, used for bulk operations, supports sub-document operations lookupIn and mutateIn.
This example, without error handling, updates two arrays in multiple documents, using JUnit and RxJava’s TestScheduler for convenience:
// Create documents like this:
// {
// "field1": ["a", "b", "c"]
// "field2": {
// "field3": [1, 2, 3]
// },
// }
List<String> docIds = new ArrayList<>(Arrays.asList("doc01", "doc02", "doc03"));
for (String docId : docIds) {
JsonDocument document =
JsonDocument.create(docId,
JsonObject.from(ImmutableMap.of(
"field1", JsonArray.from("a", "b", "c"),
"field2", JsonObject.from(ImmutableMap.of("field3", JsonArray.from(1, 2, 3)
))
)));
bucket.upsert(document);
}
// Create an observable from the document IDs to operate over
Observable<String> docIdsObs = Observable.from(docIds);
// Mutate each document by appending items to two different arrays
// After the changes, each document will look like this:
// {
// "field1": ["a", "b", "c", "e"]
// "field2": {
// "field3": [1, 2, 3, 4]
// },
// }
Observable<DocumentFragment<Mutation>>
subdocAppendObs = docIdsObs.flatMap(docId -> asyncBucket
.mutateIn(docId)
.arrayAppend("field1", "e", subdocOptions)
.arrayAppend("field2.field3", 4, subdocOptions)
.execute());
// Subscribe to the observable and await completion
TestSubscriber<DocumentFragment<Mutation>> subscriber = new TestSubscriber<>();
subdocAppendObs.subscribe(subscriber);
subscriber.awaitTerminalEvent();
// Assert the expected results
subscriber.assertCompleted();
subscriber.assertValueCount(3);
List<DocumentFragment<Mutation>> mutations = subscriber.getOnNextEvents();
for (DocumentFragment<Mutation> mutation : mutations) {
// Document mutations should have IDs matching the document IDs
assertTrue("Unexpected document ID " + mutation.id(),
docIds.contains(mutation.id()));
}
// Retrieve one of the documents and confirm the change
assertEquals("Wrong number of elements", 4,
bucket.get("doc02").content().getObject("field2").getArray("field3").size());
Since any mutation may fail, your code must handle the errors and recover accordingly, either retrying operations or tracking progress and retrying at a later time.
Also, there is no guarantee you will receive acknowledgement of a successful mutation.
If performing the mutation twice on a document will have an undesired effect, you must use both document ID and CAS value when mutating the document. See MutateInBuilder.withCas(long).
I’m using Couchbase Java SDK 1.5.1 and RxJava 1.3.2.
Regards,
Jeff