MutateIn limited to 16 operations?

I’ve been attempting to remove 20 keys from one document document all at the same time using the Node MutateIn builder. Specifically, I make a builder, call .remove("foo:NNNN") on it 20 times, and then execute it.

When I execute it, no changes are made to the document in the database, and the following is returned:

{ CouchbaseError: The server replied with an unrecognized status code. A newer version of this library may be able to decode it
  message: 'The server replied with an unrecognized status code. A newer version of this library may be able to decode it',
  code: 61 }

When I reduce the number of removals to 16, the document actually gets changed in the database.

Is there a limit of 16 subdocument operations?

Hey @splodingsocks,

Indeed there is a limit of 16 subdocument operations that can be performed on a document at once. You can find more information regarding the details of our subdocument operations here:
https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html#story-h2-8

Cheers, Brett

This limitation defined in the protocol file on the server

Hey, thanks, @brett19 and @avsej! That’s good to know.

Hey, @avsej thank you for this information, I wonder if this limit can be overridden somehow? Thank you

The maximum number of the subdocument paths is not configurable during runtime, as it is defined during compilation.

If your application requires changing so many parts of the document, why can’t you replace whole thing using regular replace/upsert operation? Or model your data so that these 16 different paths would be moved into some inner object that you can replace using single path?

Actually, my object is something like this:

{
  "favorites": [
    {
      "id": 1,
      "fp": 69.98,
      "fa": 1595330760000,
      "in": "",
      "st": "string",
      "bid": 40,
      "b": "brand",
      "ba": "40:brand",
      "cid": 563,
      "c": "category",
      "ca": "563:category"
    },
    .
    .
    .
    1500(at max)
    ]
   "totalCount": 1500
}

I need to arbitrarily get 20 favorite objects from the favorites array. You can think of this as pagination. Yes, I can get all favorites and return to the user some part of them but that approach consumes more resources. I just need 5 more slots :slight_smile:. If you know how to access a range of array elements I am eager to hear that :slight_smile:. Thank you in advance.

What other operations do you need to perform on this data structure? How often do you modify the structure? If the reads operation prevail, maybe you will store favorites in pages? Or use some tree-like structure instead?

I will need to prepend an object to the array when the user adds to his/her favorites an item. I will need to update some fields of the favorite object when the user manipulates it and I will need to remove the specific favorite object from this array when the user deletes it. For update and delete operations I may need to get the whole document or by querying or searching it I can get the index of the favorite object then manipulate it with mutateIn.

@fatihyilmaz how about you separate “favourites” into multiple pages as @avsej suggests and include the page-id in the favourite id? This should give you instant access to a particular favourite “favourites.PAGE_ID.FAVOURITE_ID”. Ah, but you wouldn’t be able to guarantee you’re getting 20+ favourites, as favourites can be deleted from the pages… I can’t see a way to maintain a separate “quick_favourites” field either, it has the same problem.
Yes, this is an interesting problem! But, I think you may have to bite the bullet and fetch the full favourites list… Well, or recompile the server.

Hi @ fatihyilmaz, for the case of getting the 20 elements, maybe you could get them in 2 separate subdoc operations, then compare the CAS values of the results to make sure the document didn’t change in between the gets. (If it did change, start over).

That way you don’t have to fetch the whole document, and you have simulated an atomic get of 20 elements.

Thank you for your valuable responses. Apparently, we cant increase multi subdoc count. As David suggests I preferred making 2 couchbase calls asynchronously. Except these, I have last another question. When making normal kv operations in case of any failover we can use getAnyFromReplica but I couldn’t found an API to do it for sub-document operations. Am I missing something? Or does sub doc api performs internally what I described?