Elasticsearch Range greater than or field does not exist - elasticsearch

So the problem is something like this I want to get posts that whose online field is greater than a time or the field does not exist and I only want to use these two clauses as a filtering mechanism i.e. they should not contribute any score towards the search and there are other clauses that do the actual searching.
Here is what I currently have
{
"query": {
"bool": {
"should": [
{"range" : {"online" : {"gte" : time}}},
{"bool": {"must_not": {"exists": {"field": "online"}}}}
],
}
}
}
The problem is I think these are contributing to the score. If a doc where the online field is greater than time it gets a score of 1.0 and if there is a doc where the online field is not present it gets a score of 0.0

You can wrap your bool should query inside the bool filter clause. In the filter clause the scoring is ignored, so the score from the range or should will not contribute any score towards the search. Modify your query as
{
"query": {
"bool": {
"filter": {
"bool": {
"should": [
{
"range": {
"online": {
"gte": 6
}
}
},
{
"bool": {
"must_not": {
"exists": {
"field": "online"
}
}
}
}
]
}
}
}
}
}

Related

Assign custom scores to clauses in boolean query in Elasticsearch

In Elasticsearch I am testing the following query:
GET sdata/_search
{
"query": {
"bool": {
"must": [
{ "match": { "f1": "sth" } }
],
"should": [
{ "match": { "f2": "sth" } }
]
}
}
}
I know that the overall score of retrieved documents depends on the number of matches they achieve. but is it possible to customize the final score so that the documents that match the should clause may be weighted much more higher than documents that match the must alone? can I add a script to determine how each clause contribute to the final score?
Thank you in advance
You can use a boost parameter along with the should clause
{
"query": {
"bool": {
"must": [
{
"match": {
"f1": "sth"
}
}
],
"should": [
{
"match": {
"f2": {
"query": "sth",
"boost": 10
}
}
}
]
}
}
}

Combining filter and must in elasticsearch

What is the difference between adding a query filter inside a must and having a query filter and a must separately?
I need to apply a filter query to a search for but either of these two queries works the same for me. I would like to know if there are any differences.
Case 1:
"query": {
"bool": {
"must": [
{
"term": {
"field": {
"value": "VALUE"
}
}
},
{
"bool": {
"filter": [
{
"script": {
"script": {
"source": """
return true;
"""
}
}
}
]
}
}
]
}
}
Case 2:
"query": {
"bool": {
"must": [
{
"term": {
"field": {
"value": "VALUE"
}
}
}
],
"filter": [
{
"script": {
"script": {
"source": """
return true;
"""
}
}
}
]
}
}
In my opinion they do not differ, but I need references. Greetings.
Both the query will work exactly the same
Refer to documentation on the boolean query to know more about your structure
must: The clause (query) must appear in matching documents and will
contribute to the score.
filter: The clause (query) must appear in matching documents. However
unlike must the score of the query will be ignored. Filter clauses are
executed in filter context, meaning that scoring is ignored and
clauses are considered for caching.
Structure of your first query where multiple bool queries are combined:
{
"query": {
"bool": {
"must": [
{
"term": {},
"bool": {
"filter": {
"script": {}
}
}
}
]
}
}
}
Structure of your second query that includes single bool query:
{
"query": {
"bool": {
"must": [
{
"term": {}
}
],
"filter": [
{
"script": {}
}
]
}
}
}
As you can see, in both the search queries the document will match only when both the term query and script query condition is satisfied
They both will work exactly the same, second one would be preferred syntax because it's not as nested as first one and easier to read.

prefixQuery in Elastic search not working

{
"from": 0,
"size": 100,
"timeout": "10m",
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"bool": {
"filter": [
{
"bool": {
"must": [
{
"term": {
"input.custom_attrs.index": {
"value": "1",
"boost": 1
}
}
}
]
}
},
{
"bool": {
"must": [
{
"prefix": {
"input.custom_attrs.value": {
"value": "An*",
"boost": 1
}
}
}
]
}
}
]
}
}
]
}
}
]
}
}
}
Explanation -
I want to search the field with "An" as prefix .
Also i am sure that there is data with value "Annual" and "Annual Fund" ,which should appears in all match search .
But these records are not appearing with prefix query as given above.I tried with regexp query and wildcard query too .But they are also not working .Please give your valuable suggestions how to make the query working.
Possible causes why it's not working
look like while indexing data you used the default mapping or text field, which uses the default standard analyzer which converts the generated tokens to lowercase.
While prefix queries are not analyzed and search term doesn't go through any analyzer and will not be lowercased.
In your case, you are searching for An, note capital A, while for Annual and Annual fund, tokens would be annual and annual and fund, hence its not matching.
Solution:
Please use an as your prefix query and you should get your search results.

How to check how many documents do not exist out of a list in elasticsearch

What will be the query to retrieve the number of documents not found in a query
This is my Query
$params['body']['query']["bool"]["filter"]["terms"]["feild"] = (list);
I want to retrieve the documents not found from the list.
If my List has (A,B,C). i just need to know that C is not indexed. I don't Need A,B,D,E,F or all of the remaining documents in index.
You can use must_not clause to achieve the negation of your query as shown below:
GET my-index/_search
{
"query": {
"constant_score": {
"filter": {
"bool": {
"must_not": {
"terms": {
"field": [
"value-1", "value-2"
]
}
}
}
}
}
}
}
must_not with aggregation will give more details about that field values which you are not expecting :-
{
"_source":false,
"query": {
"bool": {
"must_not": [
{"term": {"aFieldName": "aFieldValue"}}
]
}
},
"aggregations": {
"byLocation": {
"terms": {
"field": "aFieldName"
}
}
}
}

ElasticSearch multi_match if field exists apply filter otherwise dont worry about it?

So we got an elasticsearch instance, but a job is requiring a "combo search" (A single search field, with checkboxes for types across a specific index)
This is fine, I simply apply this kind of search to my index (for brevity: /posts):
{
"query": {
"multi_match": {
"query": querystring,
"type":"cross_fields",
"fields":["title","name"]
}
}
}
}
As you may guess from the need for the multi_match here, the schemas to each of these types differs in one way or another. And that's my challenge right now.
In one of the types, just one, there is a field that doesnt exist in the other types, it's called active and it's a basic boolean 0 or 1.
We want to index inactive items in the type for administration search purposes, but we don't want inactive items in this type to be exposed to the public when searching.
To my knowledge and understanding, I want to use a filter. But when I supply a filter asking for active to be 1, I only ever now get results from that type and nothing else. Because now it's explicitly looking for items with that field and equal to one.
How can I do a conditional "if field exists, make sure it equals 1, otherwise ignore this condition"? Can this even be achieved?
if field exists, make sure it equals 1, otherwise ignore this condition
I think it can be implemented like this:
{
"query": {
"filtered": {
"filter": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"exists": {
"field": "active"
}
},
{
"term": {
"active": 1
}
}
]
}
},
{
"missing": {
"field": "active"
}
}
]
}
}
}
}
}
and the complete query:
{
"query": {
"filtered": {
"query": {
"multi_match": {
"query": "whatever",
"type": "cross_fields",
"fields": [
"title",
"name"
]
}
},
"filter": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"exists": {
"field": "active"
}
},
{
"term": {
"active": 1
}
}
]
}
},
{
"missing": {
"field": "active"
}
}
]
}
}
}
}
}

Resources