Sub document update for a nested array document



Is it possible (If so how?) to use mutateIn and update only a fragment at apps level, so that it adds/updates the entire fragment of apps but only for “arraySubOptions2” alone, and it shouldn’t remove arraySubOptions1? I have pasted the fragment and the entire structure below?

Sample structure:

Fragment to be updated:


If i use the mutateIn option, it is treating the fragment as a string, and replaces the structure with quoted escaped String.
If I send the JsonObject as the fragment to be updated,

I get “BinaryResponse{bucket=‘bucketName’, status=INVALID_ARGUMENTS (4), request=SubDictUpsertRequest{observable=rx.subjects.AsyncSubject@147bcbe1, bucket=‘bucketName’}, content=EmptyByteBufBE}”

Does Couchbase partial JSON update?

I believe what you’re asking for it a “sub-document merge” operation - i.e. you want to merge some of the existing content with your new value.

The current Sub-Document API doesn’t support that - it will always operate on specific path(s), and all of that path(s). For example, you could perform a mutateIn on apps[0].enrollList[0].arrayOptions[0] if you wished, but that wouldn’t affect any other elements.

You may be able to restructure your documents - note you can access up to 16 paths inside a document in a single sub-document operation.

(As an aside, your current document structure isn’t best suited for sub-document access. It would probably be better if arrayOptions was actually a dictionary; with arraySubOptions1 and 2 as dictionary keys - that would allow direct access to arraySubOptions1 without having to know which array index it was under).


thanks for your response @drigby, will have to trunk that through…
I just read under Update array of object if object exist else insert new object
so I should atleast be able to replace the specific enrollList element based on a condition within the deviceInfo object field?

trying to see if that would help at the most? Would the 16 paths (update) limit apply if i replace a specific index of array field enrollList based on a condition?


I think there’s maybe some confusion about the different APIs available to you:

  • Using the Sub-Document API, you can access up to 16 paths inside a single document. There’s no predicate support; you simply specify the path you wish to write and the value to with to add.
  • Using N1QL, you can create very complex queries (including predicates) across multiple documents.

The Sub-Document API is essentially an extension of the original KV API - you still access a single document (one key), but you can access only part of the value. N1QL on the other hand is an SQL-like query language which allows much more complicated requests, at the cost of (typically) being slower than the Sub-Document API.


thanks for your inputs, but I’m having such trouble with updates to specific array index, and I could not find an example depicting this. (all the examples depict, the vanilla flavor, updates to specific fields and not a collection)
I have been trying the n1ql option, and the subdocument mutateIn operation.

Subdocument: (this isn’t doing the update at enrollInfo[x] index level as yet, as I’m unable to figure out that part)
mybucket.mutateIn(“documentIdValue”).upsert(“apps[0]”, jsonDocument.content(), subdocOptionsBuilder).execute();

where jsonDocument.content() is the JsonDocument_having the enrollList structure,
getting the error below:
“BinaryResponse{bucket=‘myBucket’, status=INVALID_ARGUMENTS (4), request=SubDictUpsertRequest{observable=rx.subjects.AsyncSubject@5b7e6593, bucket=‘myBucket’}, content=EmptyByteBufBE}”

I dont think subdocument mutateIn helps my case, as the update has to be based on the field value of the specific array Index I’m trying to update.

myBucket.query(N1qlQuery.simple(“UPDATE myBucket AS mBucket USE KEYS ‘documentId’ SET enroll = ARRAY_DISTINCT( ARRAY_APPEND( ARRAY CASE WHEN = ‘testing1’ THEN ‘arrayJsonStructure’ ELSE enroll END, ‘arrayJsonStructure’) ) FOR enroll IN app.enrollList, app IN myBucket.apps END”))

fatal error

I think the N1QL query will help, but not sure how to get subdocument set to the enroll object.

note: I’m using the java client 2.4.5