Arithmetic operations with fields - elasticsearch

Is it possible to query the result of a subtraction between two fields?
E.g. There are two fields: "start", "end". I would like documents with end - start > 10.
Can this be done directly or the only way to do is to create a new field while loading the documents with this difference?

You can use script filters using the scripting syntax explained in the scripting documentation.
For your specific issue, you might do something like
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"script": {
"script": "doc['end'].value - doc['start'].value > 10"
}
}
}
}
}
where you can replace the match_all query with your own.
As it's probably clear from the code above, you can access specific fields in your document with the sintax doc['field'] and apply specific functions to their values. In this case, .value (without parenthesis) returns the value of the field itself.

script filter in your query might be the way to go.
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-query.html

Related

Filtering documents by an unknown value of a field

I'm trying to create a query to filter my documents by one (can be anyone) value from a field (in my case "host.name"). The point is that I don't know previously the unique values of this field. I need found these and choose one to be used in the query.
I had tried the below query using a painless script, but I have not been able to achieve the goal.
{
"sort" : [{"#timestamp": "desc"}, {"host.name": "asc"}],
"query": {
"bool": {
"filter": {
"script": {
"script": {
"source": """
String k = doc['host.name'][0];
return doc['host.name'].value == k;
""",
"lang": "painless"
}
}
}
}
}
I'll appreciate if any can help me improving this idea of suggesting me a new one.
TL;DR you can't.
The script query context operates on one document at a time and so you won't have access to the other docs' field values. You can either use a scripted_metric aggregation which does allow iterating through all docs but it's just that -- an aggregation -- and not a query.
I'd suggest to first run a simple terms agg to figure out what values you're working with and then build your queries accordingly.

ElasticSearch how to get docs with 10 or more fields in them?

I want to get all docs that have 10 or more fields in them. I'm guessing something like this:
{
"query": {
"range": {
"fields": {
"gt": 1000
}
}
}
}
What you can do is to run a script query like this
{
"query": {
"script": {
"script": {
"source": "params._source.size() >= 10"
}
}
}
}
However, be advised that depending on the number of documents you have and the hardware that supports your cluster, this can negatively impact the performance of your cluster.
A better idea would be to add another integer field that contains the number of fields that the document contains, so you can simply run a range query on it, like in your question.
As Per Documentation of _source field, you can do this like that or can't get results based on fields count.
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-source-field.html

Query DSL terms filtering with script for day by numeric value

Within aggs I am able to get buckets by day of the week that are represented in numeric (1-7) keys using something like this:
"aggs" : {
"group_by_day" :{
"terms": {
"script": "doc['#timestamp'].date.dayOfWeek",
"order": {
"_key": "asc"
}
}
}
}
however I am looking for a way to add to the query filtering terms clause something like this to only show results for a monday or tuesday and haven't been able to get this:
I have tried
{
"terms": {
"script":"doc['#timestamp'].date.dayOfWeek"
}
}
and the use of script tag doesn't seem to be supported in terms query? at least how I am attempting to use it. Is there another way to get at filtering with script, or another approach (better) to get want I am trying to achieve? I am using 6.2...thanks!
Here is it:
"script":{
"script": {
"source": "doc['#timestamp'].date.dayOfWeek == 1"
}
}
Where I just handle the string to numeric conversion outside of this query, this is within a query.bool.must clause.

Is it possible to put a comment in an Elasticsearch query?

Is it possible to put a comment into an Elasticsearch query JSON? I want to be able to add some extra text to the query that's human-readable but ignored by Elasticsearch.
For example, if I have the following query:
{ "query": { "match_all": {} } }
I would like to be able to add a comment, maybe something like this:
{ "query": { "match_all": {} }, "comment": "This query matches all documents." }
Hacky workarounds (e.g., a query clause that has no effect on the results) would also be appreciated.
Seems like Elasticsearch does allow Javascript comments (/* */ and //) in JSON (Despite the JSON standard not supporting comments). So that's another option.
One solution to make this work is to use named queries, i.e. each query can be named
{
"query": {
"match_all": {
"_name": "This query matches all documents."
}
}
}
by inserting # [hash symbol] ,yes you can put comment for elastic search queries in console

Elasticsearch query based on two values

I am trying to use elasticsearch in order to find documents with a rule based on two doc properties.
Lets say the documents are in the following structure:
{
"customer_payment_timestamp" : 14387930787,
"customer_delivery_timestamp" : 14387230787,
}
and i would like to query these kind of documents and find all documents where customer_payment_timestamp is greater than customer_delivery_timestamp.
Tried the official documentation, but I couldn't find any relevant example regarding the query itself or a pre-mapped field... is it even possible?
You can achieve this with a script filter like this:
POST index/_search
{
"query": {
"bool": {
"filter": {
"script": {
"script": "doc.customer_payment_timestamp.value > doc. customer_delivery_timestamp.value"
}
}
}
}
}
Note: you need to make sure that dynamic scripting is enabled

Resources