Bug in docs with upsert and script file

Trying to do an upsert with a script file (inline scripting kept off). Simple use case (simplified further):
== mappings ===
"mappings":{
"sometype":{
"_source":{"enabled": true},
"_ttl":{"enabled":false},
"properties":{
"somefield":{"type":"long"},
"counter":{"type":"long"} }
}
}

Upsert done via curl....
curl -XPOST 'eshost:9200/test_index/sometype/11223344/_update' -d '{
"script":{
"file":"sometype-add"
},
"upsert":{
"somefield":"11223344",
"counter":0
}
}'

Have put a sometype-add.groovy in the scripts folder under /etc .. which does this:
ctx._source.counter += 1
Nothing too demanding here.
If the doc exists, the counter is updated. However... if the doc does not exist, we fail with:
{"error":"RemoteTransportException[[nodename][inet[/esserverip:9300]][indices:data/write/update]]; nested: DocumentMissingException[[index][0] [data][11223344]: document missing]; ","status":404}

I jumped through all teh relevant hoops for a few hoours. tried doc_as_upsert.. nothing. Then , out of frustration, I changed the call around to this:

curl -XPOST 'eshost:9200/test_index/sometype/11223344/_update' -d '{
"upsert":{
"somefield":"11223344",
"counter":0
},
"script":{
"file":"sometype-add"
}
}'
.. and presto! If the doc exists, it adds to the counter.. if the doc does not exist it creates it. All you have to do is put the upsert first, and the script second.... I think this is an internal bugette... but one that needs highlighting....

1 Like

Hi,
thanks for reporting this, this might indeed be a bug. Could you open an issue on github for this and add the ES version you are using?

I'm running into a similar issue - was this ever figured out? I'm going through the documentation and trying to create an upsert script. It works when the document is found (the script is executed), but if the document is not present, I get a DocumentMissingException, when the body of upsert should actually be inserted as a new doc.

I'm running ES 1.7.

Here's what I did:

  1. Enabled inline scripts (set script.indexed: on in elasticsearch.yml)

  2. Created a new script with ID indexedCalculateScore:

curl -XPOST 'localhost:9200/test/type1/ad:99998/_update' -d '{
    "script" : {
        "id": "indexedCalculateScore",
        "params" : {
            "count" : 50000
        }
    },
    "upsert" : {"counter": 3525235}
}'

> {"_id":"indexedCalculateScore","_version":1,"created":true}
  1. Inserted a test doc:
curl -XPUT localhost:9200/test/type1/ad:99999 -d '{
    "counter" : 1,
    "tags" : ["red"],
    "capture_timestamp": "2016-06-05T00:00:00+00:00",
    "timestamp": "2016-06-01T00:00:00+00:00"
}'

> {"_index":"test","_type":"type1","_id":"ad:99999","_version":1,"created":true}
  1. Now, if I update that doc, the script works:
curl -XPOST 'localhost:9200/test/type1/ad:99999/_update' -d '{
    "script" : {
        "id": "indexedCalculateScore",
        "params" : {
            "count" : 50000
        }
    },
    "upsert" : {"counter": 3525235}
}'

> {"_index":"test","_type":"type1","_id":"ad:99999","_version":2}
  1. But if I use the ID of a doc that does not exist, I get a missing document error, when a new doc should be created instead:
curl -XPOST 'localhost:9200/test/type1/ad:99998/_update' -d '{
    "script" : {
        "id": "indexedCalculateScore",
        "params" : {
            "count" : 50000
        }
    },
    "upsert" : {"counter": 3525235}
}'

> {"error":"DocumentMissingException[[test][4] [type1][ad:99998]: document missing]","status":404}

Ah, just read the end of your post - indeed, putting upsert above script fixed the issue for me. thank you @PeterC!

Glad to be of service :slight_smile: