7

I'm just trying to create or replace a document, but the API docs aren't clear on how to do this.

The upsert example shows a document being created with a counter value of 1:

client.update({
    index: 'myindex',
    type: 'mytype',
    id: '777',
    body: {
        script: 'ctx._source.counter += 1',
        upsert: {
            counter: 1
        }
    }
}, function(error, response) {
    // ...
})

I don't need the increment script, so I try to just send an upsert by itself, but I get a 400 Validation Failed: 1: script or doc is missing:

 client.update({
     index: "testindex",
     type: "testType",
     id: 1234,
     body: {
         upsert: {
             itworks: true,
             ok: "oh yeah"
         }
     }
 })

Well, let's try something silly and include the doc twice; once under doc, which would presumably replace an existing document if there was one, and once under upsert, which would be used to create a new document otherwise:

client.update({
    index: "testindex",
    type: "testType",
    id: 1234,
    body: {
        upsert: {
            itworks: true,
            ok: "oh yeah"
        },
        doc: {
            itworks: true,
            ok: "oh yeah"
        }
    }
})

That actually worked, 201 Created. 200 OK when I repeat it to replace the doc with a different one:

client.update({
    index: "testindex",
    type: "testType",
    id: 1234,
    body: {
        upsert: {
            whatever: "man"
        },
        doc: {
            whatever: "man"
        }
    }
})

But when I check the doc (client.get({index: "testindex", type: "testType", id: 1234})), I see that instead of replacing the existing doc, the new doc was merged with it.

How do you just replace a doc in Elasticsearch, with the standard Node client? The HTTP API makes it look so simple, but I've tried a bunch of permutations of that in the Node client without success. Is there no replace command? Do I have to delete and then create?

2 Answers 2

12

In Elasticsearch, to replace a document you simply have to index a document with the same ID and it will be replaced automatically.

If you would like to update a document you can either do a scripted update, a partial update or both.

To do a partial doc update you simply

Partial document update:

client.update({
  index: 'myindex',
  type: 'mytype',
  id: '1',
  body: {
    // put the partial document under the `doc` key
    doc: {
      title: 'Updated'
    }
  }
}, function (error, response) {
  // ...
})

Scripted update:

client.update({
  index: 'myindex',
  type: 'mytype',
  id: '1',
  body: {
    script: 'ctx._source.tags += tag',
    params: { tag: 'some new tag' }
  }
}, function (error, response) {
  // ...
});

More info in Elasticsearch JS documentation

Sign up to request clarification or add additional context in comments.

3 Comments

A create call with the same ID returns a 409 Conflict: document exists, or a version conflict, if I include a version that does not match the existing version.
try index instead of create
That's it! I never would have guessed the term. I was thinking of indexes like how they are used in an RDBMS, where they are mostly just an optimization.
6

This is one of the reasons I always use index instead of create:

client.index({
    "index": 'index-name',
    "type": 'mapping type',
    "id": 'id you want to create/replace',
    'body': JSON.stringify(obj)
}, function (err, resp) {
    if (err) {
        console.error(err['message'])
    }
    else {
        console.log(resp);
        return resp
    }
});

1 Comment

that's the API reference from official site of current version: elastic.co/guide/en/elasticsearch/client/javascript-api/current/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.