Say I have index like this:
{"id": "12345678", "start": 1541999620214, "end": 1541999620222 }
How do I query for documents with end-start > 10? and now-start < 60000
Simply like this:
{
"query": {
"script": {
"script": {
"source": "doc.end.value - doc.start.value < 10"
}
}
}
}
and
{
"query": {
"script": {
"script": {
"source": "System.currentTimeMillis() - doc.start.value < 60000"
}
}
}
}
As a performance optimization, though, you could store the end - start information inside your document at indexing time so you don't have to resort to scripting and your query would simply become:
{
"query": {
"range": {
"diff": {
"lt": 10
}
}
}
}
Related
I'm trying to get the difference between two fields. I'm using Elasticsearch 5.5.
I have already tried
{
"query": {
"bool": {
"filter": {
"script": {
"script": "doc['students.total_fee'].value - doc['students.paid_fee'].value"
}
}
}
}
}
but it is returning empty "hits".
I have also tried
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "students",
"query": {
"script": {
"script": {
"inline": "doc['students.total_fee'].value - doc['students.paid_fee'].value",
"lang": "expression"
}
}
}
}
}
]
}
}
and it is returning "0".
also the "script_fields" did not worked.
{ "script_fields" :
{ "difference" :
{ "script" : "doc['students.total_fee'].value - doc['students.paid_fee'].value"
} } }
suppose I have data in following format.
"_source" : {
"students" : [
{
"name" : "A",
"total_fee" : 12345,
"paid_fee" : 12344.8
},
{
"name" : "B",
"total_fee" : 23456,
"paid_fee" : 23455.6
}
]
}
Now I want to get the difference between "total_fee" and "paid_fee" for each student.
I expect to get an array of differences for all students.
Thanks in advance :D
You need to use the below query and my es version is 6.2.2. It is giving a perfect result. But remember scripting is generally CPU intensive.
If you normal field then below query working fine.
{
"size": 10,
"script_fields": {
"fare_diff": {
"script": "doc[\"students.total_fee\"].value - doc[\"students.paid_fee\"].value"
}
}
}
If you are using a nested field parameter then the query would be like below.
{
"script_fields": {
"fare_diff": {
"script": {
"lang": "painless",
"source": "int total = 0; def l = new ArrayList(); for (int i = 0; i < params['_source']['students'].size(); ++i) { l.add(params['_source']['students'][i]['total_fee'] - params['_source']['students'][i]['paid_fee']);} return l.toArray();"
}
}
}
}
Reason: Because nested documents are indexed as separate documents, they can only be accessed within the scope of the nested query, the nested/reverse_nested aggregations, or nested inner hits.
How to check for key exists in painless script map parameters.
In below query check a.toString() key exist in params
I've tried everything but didn't get it to work.
Please help me
mapping :
"id": {
"type": "long"
}
query:
{
"query":{
"bool":{
"filter":[
{
"script": {
"script": {
"lang": "painless",
"params": {
"29232":2541,
"minDistance": 0
},
"source": "def a=doc['id'].getValue();double distance=params[a.toString()]; return distance <= 1000 && distance >= params['minDistance']"
}
}
}
]
}
}
}
The params is just a Java Map object. So, the following checks if the key exists in the params and exits early with a false if it does not exist.
GET test/_search
{
"query":{
"bool":{
"filter":[
{
"script": {
"script": {
"lang": "painless",
"params": {
"29232":2541,
"minDistance": 0
},
"source": """
def a=doc['id'].getValue();
if (!params.containsKey(a.toString())) {
return false;
}
double distance=params[a.toString()];
return distance <= 1000 && distance >= params['minDistance']
"""
}
}
}
]
}
}
}
I have an Elasticsearch index as follows
{
"Price": "50.99"
},
{
"Price": "30.99"
},
{
"Price": "40.99"
},
{
"Price": "10.99"
}
I'm trying to fetch the documents based on a range of price. I want to return the documents with a price range of 30-100. But it is not returning any document.
GET index_name/_search
{
"query": {
"bool": {
"must": [
{ "range": {"Price": {"gte": 40, "lte": 100}}}
]
}
}
}
Since the Price is in String format I'm not able to fetch the documents. I don't have previledges to change the index. Is there a way to query it without changing the index?
Best way : Change the field type to float
But anyway if you want to keep the field type is string you can use painless script to do that. i.e
GET index_name/_search
{
"query": {
"bool": {
"must": {
"script": {
"script": {
"inline": "Float.parseFloat(doc['Price.keyword'].value) >= 40 && Float.parseFloat(doc['Price.keyword'].value) <= 100",
"lang": "painless"
}
}
}
}
}
}
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
I have a field with the following mapping:
birthdate: { type: :date, format: :dateOptionalTime }
I need to find everyone who were born in month of May (including all years)
Another query is to find all people who were born on 'August 25' (including all years)
What would be the query for that?
You can achieve this with a script filter
All people born in May of any year:
{
"query": {
"filtered": {
"filter": {
"script": {
"script": "doc.birthdate.date.monthOfYear == 5"
}
}
}
}
}
All people born on August 25th (any year)
{
"query": {
"filtered": {
"filter": {
"script": {
"script": "doc.birthdate.date.monthOfYear == 8 && doc.birthdate.date.dayOfMonth == 25"
}
}
}
}
}
Just for the archives, ES 7 brought some braking changes https://www.elastic.co/guide/en/elasticsearch//reference/current/breaking-changes-7.0.html#_getdate_and_getdates_removed
It is now:
POST /people/_search?size=50
{
"query": {
"bool" : {
"filter" : {
"script" : {
"script" : {
"source": "doc['jour'].value.getMonthValue() == 5",
"lang": "painless"
}
}
}
}
}
}
GET index_name/doc_type/_search
{
"query": {
"bool" : {
"filter" : {
"script" : {
"script" : {
"source": "doc.field_name.date.getMonthOfYear() == month_number",
"lang": "painless"
}
}
}
}
}
}
First question:
POST /test_index/_search
{
"query": {
"filtered": {
"filter": {
"range": {
"birthdate": {
"gte": "2015-05-01",
"lt": "2015-06-01"
}
}
}
}
}
}
Second question:
POST /test_index/_search
{
"query": {
"filtered": {
"filter": {
"range": {
"birthdate": {
"gte": "2015-08-25",
"lte": "2015-08-25"
}
}
}
}
}
}
Here's the code I used to test it:
http://sense.qbox.io/gist/36c800cabbe4143ecf72144d02e58e267c1e761a