Elasticsearch Scripted metric- list to map - elasticsearch

I have a document in sub aggregation in this format -
{
"tradeDateTime": "2022-07-11T13:07:00.000Z",
"status_count": 2,
"executingEntityIdCode": "635400BDQCJNMOGTBB61",
"status": {
"NEW": {
"tm": {
"submissionAccountName.keyword": "ACCOUNT1",
"assetClass.keyword": "EQUI",
"regulator.keyword": "BaFIN",
"status.keyword": "NEW"
}
},
"NEW-2": {
"tm": {
"submissionAccountName.keyword": "ACCOUNT1",
"assetClass.keyword": "BOND",
"regulator.keyword": "BaFIN",
"status.keyword": "NEW-2"
}
}
}
}
I need to get values from status in a map that can give me a count of unique status values. for example in this case -
NEW: 1
NEW-2 : 1
basically traverse the list and reduce it to a map.
"aggs": {
"topmostAggregation": {
"scripted_metric": {
"init_script": "state.final = []",
"map_script": "state.final.add(doc.status.value)",
"combine_script" : "Map myMap = [:]; for(t in state.final){ myMap.put(t.value,t.value) } return myMap; ",
"reduce_script" : """
return myMap;
"""
},
I am not sure how do I get value of tag inside status. This script gives me an error
"failed_shards": [
{
"shard": 0,
"index": "latest-transactions",
"node": "i5FCgkavTfCSX1c5Eq6jmQ",
"reason": {
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"myMap.put(t.value,t.value) } ",
" ^---- HERE"
],
"script": "Map myMap = [:]; for(t in state.final){ myMap.put(t.value,t.value) } return myMap; ",
"lang": "painless",
"position": {
"offset": 51,
"start": 40,
"end": 69
},
"caused_by": {
"type": "illegal_argument_exception",
"reason": "dynamic getter [java.lang.String, value] not found"
}
}
}
]

Related

Elasticsearch :: Unknown key for a START_OBJECT in [runtime_mappings]

I want to get the sum of run_time variant, by using runtime_mapping I got mistakes.
I know that it'a new feature in ES 7.12, but I can't upgrade it because it's not depend on me.
So how could I get the answer without runtime_mapping?
GET log/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"username": "xxx"
}
},{
"range": {
"time_end": {
"gte": "2021-12-01 11:40:06",
"lte": "2021-12-12 11:40:06"
}
}
}
]
}
}
, "_source": ["username", "time_start","time_submit", "time_end", "gpus_alloc"]
,
"runtime_mappings": {
"exec_time.weighted": {
"type": "long",
"script": """
long exec_time;
long timediff = doc['time_end'].date.getMillis() - doc['time_start'].date.getMillis();
String gpus = doc['gpus_alloc.keyword'].value;
int idx = gpus.lastIndexOf(':');
if(idx != -1)
exectime = timediff * Integer.parseInt(gpus.substring(idx+1));
else
exectime = 0;
emit(exectime);
"""
}
},
"aggs": {
"U1": {
"sum": {
"field": "exec_time.weighted"
}
}
}
}
the Error information is as follow:
{
"error": {
"root_cause": [
{
"type": "parsing_exception",
"reason": "Unknown key for a START_OBJECT in [runtime_mappings].",
"line": 22,
"col": 23
}
],
"type": "parsing_exception",
"reason": "Unknown key for a START_OBJECT in [runtime_mappings].",
"line": 22,
"col": 23
},
"status": 400
}

How to update and strip the first character of an array field in elasticsearch

I have the following within an index in elastic search listed as a json doc
Current
{
"bar": {
"bar": [{
"bar": [{
"bar": [{
"foo": "Y111111111111"
}
]
}
]
}
}
}
Update needed
{
"bar": {
"bar": [{
"bar": [{
"bar": [{
"foo": "111111111111"
}
]
}
]
}
}
}
How would I go about updating the index to strip the first character of the string where equal to bar?
I tried the following syntax which works for a single field but I receive an exception when running on an array field
{
"error": {
"root_cause": [
{
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"ctx._source.foo = ctx._source.foo.substring(1);",
" ^---- HERE"
],
"script": "ctx._source.foo = ctx._source.foo.substring(1);",
"lang": "painless"
}
],
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"ctx._source.foo = ctx._source.foo.substring(1);",
" ^---- HERE"
],
"script": "ctx._source.foo = ctx._source.foo.substring(1);",
"lang": "painless",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "Illegal list shortcut value [foo]."
}
},
"status": 400
}
POST test/_update_by_query
{
"query": {
"prefix": {
"foo": "Y"
}
},
"script": {
"source": "ctx._source.foo = ctx._source.foo.substring(1);"
}
Mapping
{
"TEST": {
"mappings": {
"properties": {
"bar": {
"properties": {
"bar": {
"properties": {
"bar: {
"properties": {
"bar": {
"properties": {
"foo": {
"type": "keyword"
}
}
}
}
}
}
}
}
}
}
}
}
}
I would do it as follows. Find all documents whose foo field starts with Y and then update all the foo fields by stripping the first character:
POST test/_update_by_query
{
"query": {
"prefix": {
"bar.bar.bar.bar.foo": "Y"
}
},
"script": {
"source": "ctx._source.bar.bar[0].bar[0].bar[0].foo = ctx._source.bar.bar[0].bar[0].bar[0].foo.substring(1);"
}
}
PS: the query will depend on whether your bar fields are nested or not, but in case they are not, the above query should work.

Scripted Metric Aggregation fails on unexpected = character

I'm trying to have some object containing all time deltas between two logs with the same recordId.
In order to do so, I'm executing the following query (Scripted Metric Aggregation) on elastic search, where the logs are, using fiddler:
{
"query": {
"exists": {
"field": "recordId"
}
},
"aggs": {
"deltas": {
"scripted_metric": {
"init_script": {
"source": "state.deltas = {};",
"lang": "expression"
},
"map_script": {
"source": " if (!(doc['topic'].value in state.deltas)) { state.deltas[doc['topic'].value] = {} } state.deltas[doc['topic'].value][doc['recordId'].value] = !(doc['recordId'].value in state.deltas[doc['topic'].value]) ? doc['#timestamp'].date.millisOfDay : Math.abs(state.deltas[doc['topic'].value][doc['recordId'].value] - doc['#timestamp'].date.millisOfDay) ",
"lang": "expression"
},
"reduce_script": {
"source": " res = {}; for (s in states) { for(topic in Object.keys(s.deltas)) { if (!(topic in res)) { res[topic] = {} } for(recordId in Object.keys(s.deltas[topic])) { res[topic][recordId] = !(recordId in res[topic]) ? s.deltas[topic][recordId] : Math.abs(res[topic][recordId] - s.deltas[topic][recordId]) } } } return res;",
"lang": "expression"
}
}
}
}
}
But it fails because of unexpected '=' character...
Tried other ways but it always throws the same error.
What am I missing?
{
"error": {
"root_cause": [
{
"type": "lexer_no_viable_alt_exception",
"reason": "lexer_no_viable_alt_exception: null"
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
"failed_shards": [
{
"shard": 0,
"index": "il0:il1-sys-logs-2020.10.07",
"node": "5bmIYI_iSVCtx41qEEbASg",
"reason": {
"type": "script_exception",
"reason": "compile error",
"script_stack": [
"state.deltas = {};",
" ^---- HERE"
],
"script": "state.deltas = {};",
"lang": "expression",
"caused_by": {
"type": "parse_exception",
"reason": "parse_exception: unexpected character '= ' on line (1) position (13)",
"caused_by": {
"type": "lexer_no_viable_alt_exception",
"reason": "lexer_no_viable_alt_exception: null"
}
}
}
}
],
"caused_by": {
"type": "lexer_no_viable_alt_exception",
"reason": "lexer_no_viable_alt_exception: null"
}
},
"status": 500
}

Update nested string field

I am trying to update a field image.uri by _update_by_query:
POST user/_update_by_query
{
"script": {
"source": "ctx._source.image.uri = 'https://example.com/default/image/profile.jpg'",
"lang": "painless"
},
"query": {
"bool": {
"must_not": [
{
"exists": {
"field": "image.id"
}
}
]
}
}
}
But it throws error:
{
"error": {
"root_cause": [
{
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"ctx._source.image.uri = 'https://example.com/default/image/profile.jpg'",
" ^---- HERE"
],
"script": "ctx._source.image.uri = 'https://example.com/default/image/profile.jpg'",
"lang": "painless"
}
],
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"ctx._source.image.uri = 'https://example.com/default/image/profile.jpg'",
" ^---- HERE"
],
"script": "ctx._source.image.uri = 'https://example.com/default/image/profile.jpg'",
"lang": "painless",
"caused_by": {
"type": "null_pointer_exception",
"reason": null
}
},
"status": 500
}
A sample document:
{
"image": {
"uri": "https://example.com/resources/uploads/default_files/profile/thumb/large/default_profile.jpg"
},
"created": "2018-06-06T21:49:26Z",
"uid": 1,
"name": "Jason Cameron",
"username": "jason"
}
UPDATED RESPONE
The problem could be coming from a document without image object in it.
Try to add strict mapping if possible, to avoid indexing documents without image object.
OLD RESPONSE/"\' are correct for use inside painless script as string
Your problem comes as use of ' to encapsulate your uri, strings must be encapsulated by ".
Try to modify your script as:
"script": {
"source": "ctx._source.image.uri = \"https://example.com/default/image/profile.jpg\"",
"lang": "painless"
}

elasticsearch:painless script params error

the query body:
{
"query": {
"script": {
"script": {
"lang": "painless",
"inline": "doc['TIME'].date.getHourOfDay() > 8 && doc['TIME'].date.getHourOfDay() <= 9",
"params": {
"startHour": 8,
"endHour": 9
}
}
}
},
"size": 1
}
I can get the query result from es5.0.
but when I use the params to replace the number(8 and 9),such as:
"inline": "doc['TIME'].date.getHourOfDay() > startHour &&
doc['TIME'].date.getHourOfDay() <= endHour",
"params": {
"startHour": 8,
"endHour": 9
}
...
ES return a error as below:
"caused_by": {
"type": "script_exception",
"reason": "compile error",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "Variable [startHour] is not defined."
},
...
what's the problem?

Resources