Accessing meta fields in script_fields - elasticsearch

I want some meta field in elasticsearch script_fields query,
I have tried following two ways but both failed.
First Method:
{
"query": {
"match_all": {}
},
"script_fields": {
"FIELD_NAME": {
"script": {
"lang": "painless",
"source": "params._routing"
}
}
}
}
Second Method:
{
"query": {
"match_all": {}
},
"script_fields": {
"FIELD_NAME": {
"script": {
"lang": "painless",
"source": "params['_routing']"
}
}
}
}
Is there any way to access meta fields i.e. "_routing", "_parent" ?

Related

How to get all documents from a filter in Elasticsearch?

If I deliver the empty params (see below) I would like to get all documents from Elasticsearch. How can I achieve this?
One solution is that I could write all the existing categories into an array. But I have more than 100 categories and this will not be a good solution.
Can someone please help me? Is it possible to ignore the terms if the array is empty?
POST _scripts/test{"script": {
"lang": "mustache",
"source": {
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"terms": {
"category": [
"{{#category}}",
"{{.}}",
"{{/category}}"
]}}}}}}}
If I execute the below query the results will be empty:
GET poi/_search/template{
"id": "test",
"params": {
"category" : [""]
}}
The best way to achieve this would be to proceed like this with a JSON array:
POST _scripts/test
{
"script": {
"lang": "mustache",
"source": """
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": [
{{#category}}
{
"terms": {
"category": {{#toJson}}category.values{{/toJson}}
}
}
{{/category}}
]
}
}
}
"""
}
}
Then you can execute this search template like this:
GET poi/_search/template
{
"id": "test",
"params": {
"category" : {
"values": ["cat1", "cat2", "cat3"]
}
}
}
And if you don't want to specify any categories, like this:
GET poi/_search/template
{
"id": "test",
"params": {
}
}

Date Range Query using Search Template in Elasticsearch

We are facing issue while framing date range query using search template in Elasticsearch. It is working fine, with one conditional clause, but when multiple conditions are provided, we are getting following error.
{
"script": {
"lang": "mustache",
"source": "{
\"query\":{
\"bool\":{
\"must\":[
{{#since}}
{\"range\":
{\"#timestamp\":
{
{{#from}}\"from\":\"{{from}}\"{{/from}}
}
}
},{{/since}}
{\"query_string\":
{
\"query\":\"(title:({{query_string}}))\"
}
}
]
}
}
}"
}
}
Error:
{
error: {
root_cause: [
{
type: "general_script_exception",
reason: "Failed to compile stored script [dateTemplate] using lang [mustache]",
}
],
type: "general_script_exception",
reason: "Failed to compile stored script [dateTemplate] using lang [mustache]",
caused_by: {
type: "mustache_exception",
reason: "Improperly closed variable in query-template:1",
},
},
status: 500,
}
Query:
{
"id": "dateTemplate",
"params": {
"query_string": "*"
}
}
Same is working fine for this Template:
{
"script": {
"lang": "mustache",
"source": "{\"query\":{\"bool\":{\"must\":[{{#since}}{\"range\": {\"#timestamp\": {\"from\": \"{{since}}\"}}},{{/since}}{\"query_string\":{\"query\":\"(title:({{query_string}}))\"}}]}}}"
}
}
Query
{
"id": "date",
"params": {
"query_string": "*",
"since": "2018-07-23"
}
}
First of all, I suggest you rewrite your template using triple quotes, as it's much easier to read and maintain, like this:
POST _scripts/dateTemplate
{
"script": {
"lang": "mustache",
"source": """
{
"query": {
"bool": {
"must": [
{{#since}}
{
"range": {
"#timestamp": {
{{#from}}"from": "{{from}}"{{/from}}
}
}
},
{{/since}}
{
"query_string": {
"query": "(title:({{query_string}}))"
}
}
]
}
}
}
"""
}
}
Then, the correct way to invoke that query is like this (i.e. you're missing the from variable in your params object):
{
"id": "dateTemplate",
"params": {
"query_string": "*",
"since": {
"from": "2018-07-23"
}
}
}

ElasticSearch - How can I reuse script_fields field in aggregation?

It is possible to use a script_field to compute a field, 'emp_salary', and use in an aggregation query? Here's an example.
I have a script_fields script to compute the 'emp_salary', and I want to use it in the aggregation sub query but I get
{
"query": {
"term": {
"name.keyword": "John"
}
},
"script_fields": {
"emp_salary": {
"script": {
"lang": "painless",
"source": """return 1"""
}
}
},
"aggs": {
"average": {
"avg": {
"field": "_field['emp_salary']"
}
}
}
}
but I get null for the 'emp_salary'. Am I accessing the field value wrong?
"aggregations": {
"average": {
"value": null
}
}
Thanks

ElasticSearch Script Fields accessable in sort

Is it possible to access a script_field inside a sort?
I have
search_body["script_fields"] = {
"test": {
"script": {
"lang": "painless",
"inline": skill_rating_algorithm.replace("\n", ""),
"params" : {
"param1": {....}
}
}
}
}
And as sort:
search_body["sort"] = {
"_script": {
"type": "string",
"order": "desc",
"script": {
"lang": "painless",
"inline": "def c = params._fields['test']; return c;",
}
},
"number_of_years_of_experience": {"order": "desc"},
"value.raw": {"order": "asc"},
}
But this only return errors.
I could do a sorting script but i need the value returned in the document as a separate key.
My questions is:
Can i access the script_field "test" inside the sort? (More script_fields will come and i will need different ordering)

Is it possible to update nested field by query?

I am using update by query plugin (https://github.com/yakaz/elasticsearch-action-updatebyquery/) to update documents by query.
In my case, there is nested field in document, the mapping is something like this:
"mappings": {
"mytype": {
"properties": {
"Myfield1": {
"type": "nested",
"properties": {
"field1": {
"type": "string"
},
"field2": {
"type": "long"
}
}
},
"Title": {
"type": "string"
}
}
}
}
Then I want to update the nested field Myfield1 by query with following request:
But unfortunately, it does not work.
{
"query": {
"match": {
"Title": "elasticsearch"
}
},
"script": "ctx._source.Myfield1 = [{'nestfield1':'foo blabla...','nestfield2':100},{'nestfield1':'abc...','nestfield2':200}]"
}
Does update by query support nested object?
BTW: any other ways to update document by query?
Is the update by query plugin the only choice?
This example uses _update_by_query
POST indexname/type/_update_by_query
{
"query": {
"match": {
"Title": "elasticsearch"
}
},
"script": {
"source": "ctx._source.Myfield1= params.mifieldAsParam",
"params": {
"mifieldAsParam": [
{
"nestfield1": "foo blabla...",
"nestfield2": 100
},
{
"nestfield1": "abc...",
"nestfield2": 200
}
]
},
"lang": "painless"
}
}
Nested elements need to be iterated in painless script to update values
POST /index/_update_by_query
{
"script": {
"source": "for(int i=0;i<=ctx._source['Myfield1'].size()-1;i++){ctx._source.Myfield1[i].field1='foo blabla...';ctx._source.Myfield1[i].field2=100}",
"lang": "painless"
},
"query": {
"match": {
"Title": "elasticsearch"
}
}
}
Nested elements value update if index is known
POST /index/_update_by_query
{
"script": {
"source": "ctx._source.Myfield1[0].field1='foo blabla...';ctx._source.Myfield1[0].field2=100;ctx._source.Myfield1[1].field1='abc...';ctx._source.Myfield1[1].field2=200;",
"lang": "painless"
},
"query": {
"match": {
"Title": "elasticsearch"
}
}
}
You can try with params, something like this:
"query" : {
"match_all" : {}
},
"script" : "ctx._source.Myfield1 = Myfield1;",
"params": {
"Myfield1": {
"nestfield1": "foo blabla..."
}
}
In my case I'm moving the data from not nested fields in nested fields. I need to add fake information to initialize the nested field. It looks like that:
"query" : {
"match_all" : {}
},
"script" : "ctx._source.Myfield1 = Myfield1; ctx._source.Myfield1.nestfield1 = ctx._source.Myfield1Nestfield1; ctx._source.Myfield1.nestfield2 = ctx._source.Myfield1Nestfield2;",
"params": {
"Myfield1": {
"nestfield1": "init_data"
}
}

Resources