How to create Dynamic Date variable/constant to use in watch - elasticsearch

I am trying to create a metadata field of type date to use in input, condition, action :
"metadata": { "range_start" : "now-10m" }
In the input it seems to have the desired effect.
In the action I am trying to use range_start like so:
from:{{ctx.metadata.range_start}},mode:absolute,to: {{ctx.trigger.triggered_time}}
but the result is:
(from:now-10m,mode:absolute,to:2018-01-11T10:38:27.509Z)
instead of:
(from:2018-01-11T10:28:27.509Z,mode:absolute,to:2018-01-11T10:38:27.509Z)
Any help is appreciated!

I have done something similar with a transform in my watch
"transform": {
"script": {
"source": "def payload = ctx.payload; payload.calctime = Instant.ofEpochMilli(ctx.trigger.triggered_time.getMillis()).minusSeconds(600); return payload;",
"lang": "painless"
}
Now you can reference the to and from time like this
from:'{{ctx.payload.calctime}}',mode:absolute,to:'{{ctx.trigger.triggered_time}}

Related

ElasticSearch scripting set an object value

I am trying to use a script to set several values of my Elastic document.
POST myindex/_update_by_query
{
"script" : {
"source": """
ctx._source.categories='categories';
ctx._source.myObject={};
""",
"lang": "painless"
},
"query": {
"term" : {
"name": "Tony"
}
}
}
But I can't set an object value with this painless language. However I write it, I get an error.
Is there a way to do this, maybe with a different script language ?
Thanks!
In order to create an object (i.e. a hash map), you should do it this way:
ctx._source.myObject = [:];

How to use carriage return in a script template with a runtime mapping field?

Here is an example that illustrates the problem we are having with "mustache" and the carriage return.
In our script template, we need :
a runtime mapping field : to compute a result (with a big script in our real case)
conditional template : to build search criteria according to params existence (many criteria in our real case)
We use Elasticsearch 7.16 and kibana debug console to make our tests.
We create this script template with this request :
POST _scripts/test
{
"script": {
"lang": "mustache",
"source": """{
"runtime_mappings": {
"result": {
"type": "long",
"script": {
"source": "emit({{#foo}}{{foo}}{{/foo}}{{^foo}}0{{/foo}})"
}
}
}
{{#foo}}
,"fields": [
"result"
]
{{/foo}}
}"""
}
}
Here are 2 examples of requests that show how this script works:
Request 1 : Search request with param
Return the computed field "result" with the "foo" parameter value (12345)
GET _search/template
{
"id": "test",
"params": {
"foo": 12345
}
}
Request 2 : Search request without param
Don't return computed field "result".
GET _search/template
{
"id": "test"
}
Like i said before, in our real case we have a very big "painless" script in the computed field.
For more readability, we therefore wrote this script on several lines and that's when a problem appears.
An error happened when we declare:
"source": "
emit({{#foo}}{{foo}}{{/foo}}{{^foo}}0{{/foo}})
"
instead of:
"source": "emit({{#foo}}{{foo}}{{/foo}}{{^foo}}0{{/foo}})"
Due to the JSON specifications, we cannot use carriage returns otherwise we get the following error:
Illegal unquoted character ((CTRL-CHAR, code 10)): has to be escaped using backslash to be included in string value
We also cannot use the notation with """ because it will conflict with the one used to declare the source of the script template.
Is there a trick to set the computed field script to multiple lines in Kibana debug console ?

Merge Json array using shell script

I need to merge two JSON objects based on first object keys
object1 = {
"params" : {
"type": ["type1", "type2"],
"requeststate": []
}
}
object2 = {
"params" : {
"type": ["type2", "type3", "type4"],
"requeststate": ["Original", "Revised" ],
"responsestate": ["Approved" ]
}
}
I need to merge two object based on first object key and my output should look like below
mergedobject = {
"params" : {
"type": ["type1", "type2", "type3", "type4"],
"requeststate": ["Original", "Revised"]
}
}
i searched for my case and didnt find much details Please let me know is it possible to do with shell script
My case involved with morethan 15 params object and I cant declare all the param object . Also it may grow in future and I need handle that if possible.
Please comment if you need more details. Thanks for your support

Searching on timestamp created on the fly in elasticsearch

I have external ES instance which I need to query for documents older than 6 months. Problem is they store timestamp like that:
"timestamp": {
"year": 2018,
"monthValue": 5,
"dayValue": 1,
}
Is it possible to create a range query combining these fields and getting documents "lt" "now-6m" or something like that?
You should be able to accomplish this using a Script Query. That would enable you to create a date object using the field values, and then compare that date with the current date.
Notional example
{
"query": {
"bool" : {
"filter" : {
"script" : {
"script" : {
"params": {
"monthRange": 6
},
"source": """
def today = new Date();
def timestamp = new Date(doc['timestamp']['year'].value, doc['timestamp']['monthValue'].value, doc['timestamp']['dayValue'].value);
/* Date comparison magic (I don't know Java, so you're on your own here) */
/* return result of comparison */
""",
"lang": "painless"
}
}
}
}
}
}
I've only used Painless once before, so I'm not familiar enough to give a perfect answer. But this may help you get started. If you get stuck, just ask another question specific to the issue you're having, and someone who's more familiar with Java/Painless can help you out.

ElasticSearch: Using an existing field in script param

I am trying to create a nested object and set the field value to be a document fields value. I can create a non nested field with my logic value and I can create a nested field with a hard coded value. But I cannot get the two of these things to work together.
Here is what I have so far.
Create a nested field:
{
"script": "ctx._source.displayFields = displayField",
"params": {
"displayField": {
"displayField": 11
}
}
}
Or I can use a script to fetch the value and sent a field like this:
{
"script" : "if (ctx._source['fielda'] == 'term1') {
ctx._source['displayField'] = ctx._source['field2']; }
else if (ctx._source['fielda'] == 'term2') {
ctx._source['displayFields.displayPrice'] = ctx._source['fieldb'];
}
But if I try and put a script in the param field like either of the below I always get an error. Any advice would be greatly appreciated.
Things I have tried and not worked:
{
"script": "ctx._source.displayFields = displayField",
"params": {
"displayField": {
"displayField": "tag"
},
"tag" : {
"script": "ctx._source['numberField']"
}
}
}
As well as trying to assign a script as its subfield or putting it as the value.

Resources