Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create or replace a document in Elasticsearch?

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?

like image 236
Dan Ross Avatar asked Dec 04 '22 00:12

Dan Ross


2 Answers

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

like image 178
Or Weinberger Avatar answered Dec 22 '22 07:12

Or Weinberger


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
    }
});
like image 28
smishra Avatar answered Dec 22 '22 08:12

smishra