find and replace in Elasticsearch / kibana 5.2 - elasticsearch

Is there any way to find and replace the value against particular field of my index with updated value?
In my index, lets say Index name = States_of_India, "State"="Jammu & Kashmir" is populated. I want to replace the '&' sign with "and".
How to do find and replace?

Have a look at the Update by Query API, or the Update API.
For example, if you want to replace the '&' sign with 'and' in the "State" field values, you can try something like this:
POST /index-name/_update_by_query
{
"script":
{
"lang": "painless",
"inline": "ctx._source.State = ctx._source.State.replace('&', 'and')"
}
}

Related

Elasticsearch query to remove an delete value from inconsistent array of comma-separated values

Recently, I posted the following about adding a string to existing (inconsistent) arrays in documents: ElasticSearch query to populate or append a value to a field
The marked solution is working perfectly.
But now I need to understand how to delete one of the 5-character codes from the arrays. Assuming I now need to delete the code 'ABCDE' from the documents, while leaving the other codes in the array untouched, what would that query look like?
In below script I am looping through array and creating a list by removing the given value.
Please test before running on actual data.
{
"script": {
"source": "ctx._source.customCategories.removeAll(Collections.singleton(params.catg))",
"lang": "painless",
"params": {
"catg": "c"
}
}
}

How to combine 2 fiels with different names but same value in Kibana

I set up a ELK environment with 2 different indices(index) streams. both streams have a field with the same value but the filed name is different.
is there a possibility to merge them or something like that so when i use the Kibana filter it shows me the value from both filed.
so i can set up visualizations, but when i filter on stream 1, the visualization of stream 2 is empty.
i also tried to name the indedx the same, but did not help.
Example:
index1 fieldname information.ID = 123
index2 fieldname ID = 123
i want to use the filter on both streams
You can create an alias which contains both indexes. Write a query against the alias using script fields.
In script fields you can define the new field and its source logic from underlying documents.
"script_fields": {
"my_script_field": {
"script": {
"lang": "painless",
"inline": "doc['some_field'].value + doc['another_field'].value"
}
In this way the resultset will have single field “my_script_field”

Select and Update all matching Documents

We are trying to do the following and any help would be appreciated.
Say you make a search and 100,000 documents match.
We would like to increment a counter in each document that matched. Then at the same time select the first page say the first 50.
Can this be done in one operation or may be a parallel scenario.
You could try a multi search query for such kind of maneuver:
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-multi-search.html
Basically you add several queries in a single multi search which is parallelized on the ES side, and returns a list of responses per each query.
You Can use Update by query using NEST.Let me know if you still facing any issues.
You can use update by query to do this :
{
"script": {
// fieldName is field you want to increment in document
"source": "ctx._source.fieldName=params.val", // counter increment by when query match
"lang": "painless",
"params": {
"i": 0,
"val": i+1,
}
},
"query": {
// your match condition
}
}

QueryDSL _id query within script

I am using Elasticsearch & Kibana v5.6 and within devTools, I am able to use script within querydsl to query for a doc on a fieldname = value, ie:
GET indexA/_search
{
"query":{ "script":{ "script": """
def a = doc['field1'].value;
return a == 'value1';
"""}}
}
Above would return all doc that has 'value1' as value within the field called 'field1'. But I am unable to search on _id, official doc says that prior to v6 we should use _uid instead so I have tried that with no luck. I am using script because after I am able to use _uid to get value of _id, essentially I want to do some value comparison similar to below:
GET indexA/_search
{
"query":{ "script":{ "script": """
def a = doc['field1'].value;
def b = doc['_uid'].value;
return a == b;
"""}}
}
I think devTools is where i want to execute this instead of other places. Any pointers are appreciated
You are referring to Query Id's document or this one but deploying in the wrong context you need to define id's in the separate head of ids or put under term field _id.

Project the sum of all fields in a document that match a regular expression, in elasticsearch

In Elasticsearch, I know I can specify the fields I want to return from documents that match my query using {"fields":["fieldA", "fieldB", ..]}.
But how do I return the sum of all fields that match a particular regular expression (as a new field)?
For example, if my documents look like this:
{"documentid":1,
"documentStats":{
"foo_1_1":1,
"foo_2_1":5,
"boo_1_1:3
}
}
and I want the sum of all stats that match _1_ per document?
You can define an artificial field called script_field that contains a small Groovy script, which will do the job for you.
So after your query, you can add a script_fields section like this:
{
"query" : {
...
},
"script_fields" : {
"sum" : {
"script" : "_source.documentStats.findAll{ it.key =~ '_1_'}.collect{it.value}.sum()"
}
}
}
What the script does is simply to retrieve all the fields in documentStats whose name matches _1_ and sums all their values, in this case, you'll get 4.
Make sure to enable dynamic scripting in elasticsearch.yml and restart your ES node before trying this out.

Resources