ElasticSearch: Using an existing field in script param - elasticsearch

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.

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 = [:];

Compare two fields in same document without using script elasticsearch

We are using elastic version 7.10.2. I want to compare two fields from a same document.Scripting is disabled in my organization.
Kindly help in building below query without using script.
Here my query is : nickname is null or nickname is empty or nickname is equal to firstname.
Hard part is how to build query to get the records which have nickname is equal to firstname
Relevant script query to be converted to normal query :
{
"query": {
"bool": {
"must": [{
"script": {
"script": {
"inline": "doc['nickname.keyword'].value==null || doc['nickname.keyword'].value =='' || doc['nickname.keyword'].value == doc['firstname.keyword'].value",
"lang": "painless",
}
}
}]
}
}
}
I see you are already comparing the nickname.keyword to your firstname also mentioned this is the hard part, for this why you need a script, you can simply use the search query on this keyword field and get the result you want.
You can use below term query for it.
{
"query": {
"term": {
"nickname.keyword": {
"value": "your-nickname", // provide your nickname as value
}
}
}
}

Getting Distinct fields from Elasticsearch

I have 1Million documents which has a field called id.The id field of all the 1Million docs are different.
Eg:1.id:http://www.bing.com/search?q=malaysia. 2.id:http://www.google.com/search?q=singapore. 3.id:http://www.bing.com/search?q=india. 4.id:http://www.google.com/search?q=america 5.id:http://www.duckduckgo.com/?q=africa 6.id:http://www.duckduckgo.com/?q=asia
Can someone help me to form a query to get only the 3 distinct urls here.I just want to get google.com,bing.com,duckduckgo.com .
Well can text the syntax, but this should work. Just use a script to split your url string.
{
"aggs": {
"urls": {
"terms": {
"field": "id",
"script" : "def path = doc['id'].value; int currentSplit = path.indexOf("//"); if (currentSplit > 0) { path = path.substring(currentSplit + 1); currentSplit = path.indexOf("/"); if (currentSplit > 0) { path = path.substring(0, currentSplit) } } return path"
}
}
}
}
The best practice should be to index the domain name on the document if you need this aggregation a lot :).

How to use special document fields in scripts in elastic?

I'm trying to write query with custom script in elasticsearch:
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-filter.html#query-dsl-script-filter
https://www.elastic.co/guide/en/elasticsearch/reference/master/modules-scripting.html.
This is useful when you need to compare two document fields.
Everything worked fine, until I decide to use special document field (ex: _id, _uid, etc). The query always returns empty results and there is no errors if I use it like this: doc['_id'].value.
So how to use, for example, "_id" field of a document in a custom script?
The _id is indexed in the uid field, using this format: type#id.
So, your script should look like this (for a type called my_type and an ID of 1):
{
"query": {
"filtered": {
"filter": {
"script" : {
"script" : "doc['_uid'].value == 'my_type#1'"
}
}
}
}
}
A more elaborate solution, to take out the id ES-way is like this:
{
"query": {
"filtered": {
"filter": {
"script": {
"script": "org.elasticsearch.index.mapper.Uid.splitUidIntoTypeAndId(new org.apache.lucene.util.BytesRef(doc['_uid'].value))[1].utf8ToString() == '1'"
}
}
}
}
}
where org.elasticsearch.index.mapper.Uid.splitUidIntoTypeAndId(new org.apache.lucene.util.BytesRef(doc['_uid'].value))[1] is the id and org.elasticsearch.index.mapper.Uid.splitUidIntoTypeAndId(new org.apache.lucene.util.BytesRef(doc['_uid'].value))[0] is the type.

Use search fields as parameters in script_fields

Background: the parameter is user-supplied so I can't enable scripting but only script_file.
I'm trying to use a field value as a param,
I will replace the XXX below to a field name in the original search result,
"script_fields": {
"my_field": {
"script_file": "my_test",
"params": {
"my_var": "XXX"
}
}
}
But I couldn't find relevant part in the document here, what is the syntax?
You can refer to the field in the script.
"script_fields": {
"my_field": {
"script_file": "myScript",
"params": {
"my_var": "fieldName"
}
}
}
Now from the script use the field name parameter to refer to that field.
myScript -
var fieldValue = doc[my_var].value
You can read more on the same here.

Resources