Cannot apply [*] operation to types [org.elasticsearch.index.fielddata.ScriptDocValues.Doubles] and [java.lang.Double] - elasticsearch

Here is the mappeing of the attribute for the index-
"hoi" : {
"type" : "float"
}
This is the query that I want to execute. I want to change my attribute hoi with dynamic value and sort the doc on top of that, don't want to use runtime mapping as I have lower version of ES-
GET test/_search
{
"sort" : {
"_script" : {
"type" : "number",
"script" : {
"lang": "painless",
"source": "doc['hoi'] * params.factor",
"params" : {
"factor" : 1.1
}
},
"order" : "asc"
}
}
}
Error-
{
"error" : {
"root_cause" : [
{
"type" : "script_exception",
"reason" : "runtime error",
"script_stack" : [
"doc['hoi'] * params.factor",
" ^---- HERE"
],
"script" : "doc['hoi'] * params.factor",
"lang" : "painless",
"position" : {
"offset" : 40,
"start" : 0,
"end" : 47
}
}
],
"type" : "search_phase_execution_exception",
"reason" : "all shards failed",
"phase" : "query",
"grouped" : true,
"failed_shards" : [
{
"shard" : 0,
"index" : "test",
"node" : "5sfrbDiLQDOg82_sneaU1g",
"reason" : {
"type" : "script_exception",
"reason" : "runtime error",
"script_stack" : [
"doc['hoi'] * params.factor",
" ^---- HERE"
],
"script" : "doc['hoi'] * params.factor",
"lang" : "painless",
"position" : {
"offset" : 40,
"start" : 0,
"end" : 47
},
"caused_by" : {
"type" : "class_cast_exception",
"reason" : "Cannot apply [*] operation to types [org.elasticsearch.index.fielddata.ScriptDocValues.Doubles] and [java.lang.Double]."
}
}
}
]
},
"status" : 400
}
How to make it work?

doc['hoi'] itself is of type org.elasticsearch.index.fielddata.ScriptDocValues.Doubles and params.factor is of type java.lang.Double.
So the error you get means that some document has multiple values in your hoi field. So you need to reference it with doc['hoi'].value * params.factor instead, which will take the first hoi value from the array to compute the sort.
You can also check how many values there are with doc['hoi'].size().
UPDATE
If some docs don't have any values for hoi then you can adapt the script like this:
doc['hoi'].size() > 0 ? doc['hoi'].value * params.factor : 0

Related

Elasticsearch script query started to fail suddenly

We have had this query for a long time
{
"size": 50,
"query": {
"match_all": {}
},
"version": false,
"seq_no_primary_term": false,
"sort": [
{
"_script": {
"script": {
"source": "(doc[params.f].size() != 0) ? (params.m['' + doc[params.f].value] ?: params.o): params.o",
"lang": "painless",
"params": {
"f": "scoreSerial",
"m": {
"0": "UNDEFINED",
"1": "FRUSTRATED",
"2": "TOLERATED",
"3": "SATISFIED"
},
"o": "ZZZZZ"
}
},
"type": "string",
"order": "asc"
}
}
]
}
This suddenly stopped working with the error
{
"error" : {
"root_cause" : [
{
"type" : "bootstrap_method_error",
"reason" : "bootstrap_method_error: CallSite bootstrap method initialization exception"
}
],
"type" : "search_phase_execution_exception",
"reason" : "all shards failed",
"phase" : "query",
"grouped" : true,
"failed_shards" : [
{
"shard" : 0,
"index" : "visit-global-standard-w2022.31",
"node" : "olbLlZh7RYuwaf5S-B9v8g",
"reason" : {
"type" : "script_exception",
"reason" : "runtime error",
"script_stack" : [
"(doc[params.f].size() != 0) ? (params.m['' + doc[params.f].value] ?: params.o): params.o",
" ^---- HERE"
],
"script" : "(doc[params.f].size() != 0) ? (params.m['' + doc[params.f].value] ?: params.o): params.o",
"lang" : "painless",
"position" : {
"offset" : 58,
"start" : 0,
"end" : 88
},
"caused_by" : {
"type" : "bootstrap_method_error",
"reason" : "bootstrap_method_error: CallSite bootstrap method initialization exception"
}
}
}
],
"caused_by" : {
"type" : "bootstrap_method_error",
"reason" : "bootstrap_method_error: CallSite bootstrap method initialization exception"
}
},
"status" : 400
}
The mapping of scoreSerial is
"scoreSerial" : {
"type" : "long"
}
It was working for more than 3 years. We are now on the 7.10 (for more than 6 months, when the above script was working) ES version. But suddenly it started to fail.
The strange thing is that it is not happening in all environments. Is it some java version related or something else? We can not also reproduce this locally.
It might have to do with type coercion, I've seen similar problems in the past (although not with painless but groovy), so simply replacing
'' + doc[params.f].value
by
doc[params.f].value.toString()
might do the trick
(i.e. explicitly getting the string version of the doc value instead of relying on type coercion). What you did should work according to the docs, though.

cannot convert MethodHandle(Dates)JodaCompatibleZonedDateTime to (Object)double

I am trying to add conditions if field exist, then sort according to it otherwise use another field. Since one of either will exist.
Here is my query:
GET /my_index/_search
{
"query": {
"match_all": {}
},
"sort": {
"_script": {
"type":"number",
"script": "if(doc['contextDates.event.date'].value != 0){ return doc['contextDates.event.date'].value} else { return doc['contextDates.start.date'].value}",
"order": "asc"
}
}
}
When I execute this query, I get following error:
"failed_shards" : [
{
"shard" : 0,
"index" : "my_inedx",
"node" : "UxKwS8SIR-uIbzo5_0IbcQ",
"reason" : {
"type" : "script_exception",
"reason" : "runtime error",
"script_stack" : [
"return doc['contextDates.event.date'].value} else { ",
" ^---- HERE"
],
"script" : "if(doc['contextDates.event.date'].value != 0){ return doc['contextDates.event.date'].value} else { return doc['contextDates.start.date'].value}",
"lang" : "painless",
"position" : {
"offset" : 84,
"start" : 47,
"end" : 99
},
"caused_by" : {
"type" : "wrong_method_type_exception",
"reason" : "cannot convert MethodHandle(Dates)JodaCompatibleZonedDateTime to (Object)double"
}
}
}
]
I have tried Double.parseDouble method as well but it doesn't work. This is what I have inside document for contextDates
"contextDates" : {
"event" : {
"date" : "2020-06-26T00:00:00.000Z",
"resolution" : "day",
"score" : 0,
"type" : "event"
}
}
The doc value you're getting is of type JodaCompatibleZonedDateTime which you're trying to compare to a double value, so you need to modify your script like this
if(doc['contextDates.event.date'].value.getMillis() != 0){ return doc['contextDates.event.date'].value.getMillis()} else { return doc['contextDates.start.date'].value.getMillis()}

Elasticsearch suggest from multiple indices

I am working on Elasticsearch. I want to use search suggestor for multiple indices at a time. I have two indices, tags and pool_tags which has name field in each index. How to use suggestor on this two indices having a similarly named field name.
I tried naming the suggestor (pool_tag_suggest in pool_tags) differently and I tried. Here are the mappings
tags:
{
"tags" : {
"mappings" : {
"properties" : {
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword"
},
"suggest" : {
"type" : "completion",
"analyzer" : "simple",
"preserve_separators" : true,
"preserve_position_increments" : true,
"max_input_length" : 50
}
}
}
}
}
}
}
pool_tags:
{
"pool_tags" : {
"mappings" : {
"properties" : {
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword"
},
"pool_tag_suggest" : {
"type" : "completion",
"analyzer" : "simple",
"preserve_separators" : true,
"preserve_position_increments" : true,
"max_input_length" : 50
}
}
}
}
}
}
}
WHAT I TRIED
POST pool_tags,tags/_search
{
"suggest": {
"tags_suggestor": {
"text": "ww",
"term": {
"field": "name.suggest"
}
},
"pooltags_suggestor": {
"text": "ww",
"term": {
"field": "name.pool_tag_suggest"
}
}
}
}
ERROR
{
"error" : {
"root_cause" : [
{
"type" : "illegal_argument_exception",
"reason" : "no mapping found for field [name.suggest]"
},
{
"type" : "illegal_argument_exception",
"reason" : "no mapping found for field [name.pool_tag_suggest]"
}
],
"type" : "search_phase_execution_exception",
"reason" : "all shards failed",
"phase" : "query",
"grouped" : true,
"failed_shards" : [
{
"shard" : 0,
"index" : "pool_tags",
"node" : "g2rCnS4PQMWyldWABVJawQ",
"reason" : {
"type" : "illegal_argument_exception",
"reason" : "no mapping found for field [name.suggest]"
}
},
{
"shard" : 0,
"index" : "tags",
"node" : "g2rCnS4PQMWyldWABVJawQ",
"reason" : {
"type" : "illegal_argument_exception",
"reason" : "no mapping found for field [name.pool_tag_suggest]"
}
}
],
"caused_by" : {
"type" : "illegal_argument_exception",
"reason" : "no mapping found for field [name.suggest]",
"caused_by" : {
"type" : "illegal_argument_exception",
"reason" : "no mapping found for field [name.suggest]"
}
}
},
"status" : 400
}

Elasticsearch - get docs with array field size greater than 1

I want to get all docs with a field, which is an array, with size greater than 1.
I'm using the following command:
curl -H "Content-Type: application/json" -XGET '127.0.0.1:9200/poly/_search?pretty' -d '
{ "query": { "bool": { "filter": { "script" : { "script" : "doc['emoji'].length > 1" } } } } }
'
but I get the following error:
{
"error" : {
"root_cause" : [
{
"type" : "script_exception",
"reason" : "compile error",
"script_stack" : [
"doc[emoji].length > 1",
" ^---- HERE"
],
"script" : "doc[emoji].length > 1",
"lang" : "painless",
"position" : {
"offset" : 4,
"start" : 0,
"end" : 21
}
}
],
"type" : "search_phase_execution_exception",
"reason" : "all shards failed",
"phase" : "query",
"grouped" : true,
"failed_shards" : [
{
"shard" : 0,
"index" : "poly",
"node" : "Dnp4BI4YSgCz-C-p8NmcTg",
"reason" : {
"type" : "query_shard_exception",
"reason" : "failed to create query: compile error",
"index_uuid" : "HlWRuJb5TY-L_2_9iyuVmg",
"index" : "poly",
"caused_by" : {
"type" : "script_exception",
"reason" : "compile error",
"script_stack" : [
"doc[emoji].length > 1",
" ^---- HERE"
],
"script" : "doc[emoji].length > 1",
"lang" : "painless",
"position" : {
"offset" : 4,
"start" : 0,
"end" : 21
},
"caused_by" : {
"type" : "illegal_argument_exception",
"reason" : "cannot resolve symbol [emoji]"
}
}
}
}
],
"caused_by" : {
"type" : "script_exception",
"reason" : "compile error",
"script_stack" : [
"doc[emoji].length > 1",
" ^---- HERE"
],
"script" : "doc[emoji].length > 1",
"lang" : "painless",
"position" : {
"offset" : 4,
"start" : 0,
"end" : 21
},
"caused_by" : {
"type" : "illegal_argument_exception",
"reason" : "cannot resolve symbol [emoji]"
}
}
},
"status" : 400
}
Nevertheless, the field "emoji" exists in my ElasticSearch docs, as you can see in the result to the following command:
curl -H "Content-Type: application/json" -XGET '127.0.0.1:9200/poly/_search?pretty' -d '
{
"_source": ["emoji"],
"query" : {
"constant_score" : {
"filter" : {
"exists" : {
"field" : "emoji"
}
}
}
}
}
'
Here is the result for the previous command:
"took" : 28,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10000,
"relation" : "gte"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "poly",
"_type" : "_doc",
"_id" : "1307256887860174848",
"_score" : 1.0,
"_source" : {
"emoji" : [
"❤️"
]
}
},
{
"_index" : "poly",
"_type" : "_doc",
"_id" : "1278766523134414848",
"_score" : 1.0,
"_source" : {
"emoji" : [
"⏩"
]
}
},
{
"_index" : "poly",
"_type" : "_doc",
"_id" : "1298632385605431296",
"_score" : 1.0,
"_source" : {
"emoji" : [
"\uD83D\uDC47\uD83C\uDFFF",
"\uD83D\uDC47\uD83C\uDFFF",
"\uD83D\uDC47\uD83C\uDFFF",
"\uD83D\uDC47\uD83C\uDFFF"
]
}
},
{
"_index" : "poly",
"_type" : "_doc",
"_id" : "1300563120184651776",
"_score" : 1.0,
"_source" : {
"emoji" : [
"\uD83D\uDC4D",
"\uD83D\uDE00",
"\uD83D\uDE80"
]
}
},
]
}
}
Can someone tell me why I'm getting that error above?
You need to skip characters in your command check command below:
Script:
"script": {"script": "doc['\''emoji'\''].length > 1"
Command:
curl -H "Content-Type: application/json" -XGET '127.0.0.1:9200/poly/_search?pretty' -d '{ "query": {"bool": {"filter": {"script": {"script": "doc['\''emoji'\''].length > 1"}}}}}'

Elasticsearch script - variable not defined

I'm following an Elasticsearch tutorial, but ran into a problem when trying to use parameters in a script.
Step 1: Create a new document - OK (index = website; type = blog; id = 1)
curl -XPUT localhost:9200/website/blog/1?pretty -d '{
"title":"my first post",
"tags" : [ "tag1" ]
}'
Step 2: Use script to append an extra value to tags array - ERROR
curl -XPOST localhost:9200/website/blog/1/_update?pretty -d '{
"script" : "ctx._source.tags+=new_tag",
"params" : {
"new_tag" : "tag2"
}
}'
The error message is this, mentioning "reason" : "Variable [new_tag] is not defined." But I have defined the variable new_tag as described on the tutorial page. What am I doing wrong?
"error" : {
"root_cause" : [
{
"type" : "remote_transport_exception",
"reason" : "[mrukUvA][127.0.0.1:9300][indices:data/write/update[s]]"
}
],
"type" : "illegal_argument_exception",
"reason" : "failed to execute script",
"caused_by" : {
"type" : "script_exception",
"reason" : "compile error",
"caused_by" : {
"type" : "illegal_argument_exception",
"reason" : "Variable [new_tag] is not defined."
},
"script_stack" : [
"ctx._source.tags+=new_tag",
" ^---- HERE"
],
"script" : "ctx._source.tags+=new_tag",
"lang" : "painless"
}
},
"status" : 400
}
Step 2 (retry) Qualifying new_tag with params - ERROR
curl -XPOST localhost:9200/website/blog/1/_update?pretty -d '{
"script" : {
"inline": "ctx._source.tags+=params.new_tag",
"params" : {
"new_tag" : "tag2"
}
}
}'
Gives error
{
"error" : {
"root_cause" : [
{
"type" : "remote_transport_exception",
"reason" : "[mrukUvA][127.0.0.1:9300][indices:data/write/update[s]]"
}
],
"type" : "illegal_argument_exception",
"reason" : "failed to execute script",
"caused_by" : {
"type" : "script_exception",
"reason" : "runtime error",
"caused_by" : {
"type" : "class_cast_exception",
"reason" : "Cannot cast java.lang.String to java.util.ArrayList"
},
"script_stack" : [
"ctx._source.tags+=params.new_tag",
" ^---- HERE"
],
"script" : "ctx._source.tags+=params.new_tag",
"lang" : "painless"
}
},
"status" : 400
}
As a sanity check to make sure the document is valid
$ curl -XGET localhost:9200/website/blog/1?pretty
{
"_index" : "website",
"_type" : "blog",
"_id" : "1",
"_version" : 27,
"found" : true,
"_source" : {
"title" : "my first post",
"tags" : [
"tag1"
]
}
}
So the document does have the valid field tag which is an array.
Your syntax is slightly off, if you have parameters you need to inline the script. Try this:
curl -XPOST localhost:9200/website/blog/1/_update?pretty -d '{
"script" : {
"inline": "ctx._source.tags.add(params.new_tag)",
"params" : {
"new_tag" : "tag2"
}
}
}'
you can use "inline" although it is deprecated. now you alse can use "source" to replace "inline" for no warnings. for example:
"script" : {
"source": "ctx._source.tags.add(params.new_tag)",
"params": {
"new_tag":"tag1"
}
}

Resources