2
votes

I have documents that would look like this:

{
"name": "n",
"age": 22
//other properties

"hash": "XyRZHDJJD6738..." //This property contains the hash of the object (calculated by the client)
}

From the client, I should whether:

  • Update the document using its key (known), ONLY if the hash is different (=> The stored object and the new object are not the same)

  • Insert the document if the Key doesn't exist

This operation is done in a bulk mode on a relatively large dataset, with concurrent access => So fetching the document then updating is not an option.

Is there a way to do this in Couchbase (5.1+)?

1
How many attributes your document has? does it have a complex structure? (nested attributes) - deniswsrosa
best option: Given key get hash, cas only using SUBDOC API then if not present or not same hash do UPSERT. - vsr

1 Answers

2
votes

With a tweak to the document model, you could have something like this:

{
    "name": "n",
    "age": 22,
    "applied_hashes": {
        "XyRZHDJJD6738": null,
        "AB2343DCxdsAd": null,
        // ... other hashes
    }
}

Now you can do each update as a Sub-Document operation, with the first spec being to try and insert the hash of the update into applied_hashes. If that hash/update has previously been applied, then this insert will fail, and as Sub-Document is atomic no changes will be made to the document.

With Java SDK 3.x this looks like:

try {
  collection.mutateIn("id",
          Arrays.asList(
                  MutateInSpec.insert("applied_hashes.XyRZHDJJD6738", null).createPath(),
                  MutateInSpec.upsert("age", 24)
                  // .. other parts of update XyRZHDJJD6738 here
          ));
}
catch (PathExistsException err) {
  // Update XyRZHDJJD6738 has already been applied
  // No changes have been made to the document
}