How to remove from array with subdoc-api?

Java SDK: v2.4.1

My use-case:
I want to maintain a list of children-ids on each master. Each child also has a masterId and adds itself to the master in our code using arrayAddUnique.

Now I also want to remove the child-id from the master e.g. when the child is removed or assigned to a different master.

I am currently adding to an array using SubdocumentAPI via:

bucket.mutateIn("masterId1").arrayAddUnique("childrenids","childId1", true).execute();

Is it possible to remove from an array too? Something like:

bucket.mutateIn("masterId1").arrayRemove("childrenids","childId1", true).execute();

Haven’t found a method ‘arrayRemove’ yet, although on this site it says:

Mutating Array Fields
The sub-document API supports a similar set of commands on arrays as on dictionaries. It also adds the ability to push items to the beginning or the end of an array, without having to explicitly check the current length of the array.

Deleting an existing array element (reducing the array size by 1) using remove.

Does this ‘remove’ method exist or is it called differently in the Java SDK?

1 Like

You can only remove an array element by index - e.g. REMOVE("array[2]")

If you want to be able to remove elements by value you need to use a dictionary - for example you could instead model your set by a dictionary where the elements are keys (and just use empty values).

That would allow you to remove by key.

1 Like

This was a very useful hint.
It took me a while to figure out the syntax how I have to do this, but it seems to work.

This is how I add to the dictionary:

DocumentFragment<Mutation> resultMutation = bucket.mutateIn("masterId1").upsert("childrenids" +"." + Expression.i("childId1").toString(), null, true).execute();

And this is how I remove the key again:

DocumentFragment<Mutation> execute = bucket.mutateIn("masterId1").remove("childrenids" + "." + Expression.i("childId1").toString()).execute();

I’ve put the Expression.i( because my ids look a bit more complex e.g. dsrecord::oid2:default:e96876b2e6e711e6b8f3e4ce8f208bf2 so I guess I need to escape special characters.

I wish there will be native support for removing simple strings from a set in the future.
From reading this sourcecode it looks like operations like setRemove under the hood still fetch the whole document.
I would prefer having Couchbase Server handle this internally more efficiently without the extra roundtrip.

1 Like