UPSERT only a single document

I would like to UPDATE a single document in a bucket with new values:

UPDATE bucket_name USE KEYS 'document_id' SET variable1 = new_value1

UPDATE bucket_name USE KEYS 'document_id' SET variable2 = new_value2

If variable1 and variable2 don’t exist in the document, then I want them to be added (UPDATE will fail if a variable does not exist).

I thought I could use UPSERT to resolve this, but from what I see, UPSERT will apply changes to ALL documents in a bucket, but I want to UPSERT to only a single document. How can I achieve this?

Hi @deamontg, which version are you using? UPDATE works as expected.

select meta().id, * from default use keys "k_blr" ;
[
  {
    "default": {
      "country": "India",
      "faa": "BLR",
    },
    "id": "k_blr"
  }
]

update default use keys "k_blr" set faa = "blr2", name = "Bangalore" returning *;
[
  {
    "default": {
      "country": "India",
      "faa": "blr2",
      "name": "Bangalore"
    }
  }
]
2 Likes

@deamontg,

In N1QL UPDATE, if you update a nonexistent field, we simply ADD the field to the document and set it to the value specified.

On the reverse, if you want to remove a field, simply set the field to MISSING.

update default use keys "k_blr" set name = MISSING returning *;

Thanks for the replies, and for the advice. I am still being faced with an issue. Suppose I have this file:

{
  "id": "12345"
}

If I try to do this:

UPDATE bucket_name USE KEYS 'document_id' SET dictionary.value = new_value

The expected output should be:

{
  "id": "12345"
  "dictionary": {
    "value": "new_value"
  }
}

But this does NOT happen, the document remains the same. If the key “dictionary” existed beforehand though, then the update would work as expected.

UPDATE doesn’t create new objects, you’ll have to create the object before creating elements within it.
The following will do the job.

UPDATE bucket_name USE KEYS 'document_id' SET dictionary = CASE dictionary WHEN MISSING THEN {} ELSE dictionary, dictionary.value = new_value

Awesome, that’s exactly what I was looking for. Thank you!

I ended up using this:

UPDATE bucket_name USE KEYS 'document_id' SET dictionary = CASE
WHEN `dictionary` IS MISSING THEN {} ELSE `dictionary` END,
dictionary.value = 'new_value'

you can try this as well to create/update object field. It works irrespective of whether ‘dictionary’ exists already…

update default use keys "document_id" set dictionary = { "value": "new_value" } returning *;