Java Sub-Doc Array Path Insert

Hello,

I am trying to update some Java SDK 2.7 code to 3.3. I have a method which will write (or edit, or delete) an arbitrary value at an arbitrary path inside a document. However, I cannot get array paths to work in SDK 3.3.

Here is my code:

Collection collection = bucket.defaultCollection();
List specs = new ArrayList<>();
// there’s a loop here but let’s consider a single path
specs.add(MutateInSpec.upsert(“myArray[0]”, “someNewValue0”).createPath());
MutateInOptions options = MutateInOptions.mutateInOptions()
.storeSemantics(StoreSemantics.UPSERT) ;
// note: for delete or upsert with CAS value I use StoreSemantics.REPLACE

collection.mutateIn(“MY::DOCUMENT::ID”, specs, options);

I try this with this example document. Goal is to change the first value in this array (I could live with a case where the value is inserted before the existing element, or if the existing element is replaced. Either is actually fine in my use case. I just need to know what it will do.)

{
“myArray”: [ “someOldValue0”]
}

This fails with SUBDOC_MULTI_PATH_FAILURE:

com.couchbase.client.core.error.CouchbaseException: Unexpected SubDocument response code {“completed”:true,
(some fields cut out here)
“path”:“myArray[0]”,
“requestType”:“SubdocMutateRequest”,
“retried”:0,
“service”:{“bucket”:“my_bucket”,“collection”:“_default”,“documentId”:“MY::DOC::ID”,
“errorCode”:{“description”:“Subdoc: Some (or all) commands failed. Inspect payload for details”,“name”:“SUBDOC_MULTI_PATH_FAILURE”},“opaque”:“0x84c”,“scope”:“_default”,“type”:“kv”,“vbucket”:723},“status”:“SUBDOC_FAILURE”,“subdocStatus”:“PATH_INVALID”,“timeoutMs”:2500,“timings”:{“dispatchMicros”:58390,“encodingMicros”:542445,“totalDispatchMicros”:58390,“totalServerMicros”:0,“totalMicros”:798528,“serverMicros”:0}
}

The “remove” operation actually works:

specs.add(MutateInSpec.remove(“myArray[0]”));

Only upsert fails.

Hi @jc,

The upsert sub-document operation is not valid when the path refers to an array element. To replace an existing array element, use the replace operation. To insert an array element, use one of arrayInsert, arrayAppend, or arrayPrepend (or if you want set semantics, arrayAddUnique).

If your goal is to implement: “if the array is empty, then add an element; otherwise, replace the zero-th element”, I don’t know how to do that with a single sub-document operation.

If you have working code for SDK 2, the Couchabse Java SDK 2 Migration Kit has some helpers for migrating subdocument operations from SDK 2 to SDK 3.

Thanks,
David

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.