Elasticsearch Function Score Query with Should Clause in Bool Query - elasticsearch

This is a story of 2 queries. One returns results, while the other does not. Why?
Query that returns results:
{
"index":"my_index",
"type":"places",
"body":{
"from":0,
"size":"12",
"sort":{
"_score":{
"order":"desc"
}
},
"query":{
"function_score":{
"query":{
"bool":{
"must":[
],
"should":[
],
"must_not":[
],
"filter":[
]
}
},
"functions":[
{
"gauss":{
"location":{
"origin":{
"lat":"41.243368",
"lon":"-116.79711"
},
"offset":"0mi",
"scale":"100mi"
}
}
}
],
"score_mode":"sum",
"boost_mode":"sum"
}
}
}
}
Query that does NOT return results:
{
"index":"my_index",
"type":"places",
"body":{
"from":0,
"size":"12",
"sort":{
"_score":{
"order":"desc"
}
},
"query":{
"function_score":{
"query":{
"bool":{
"must":[
],
"should":[
{
"terms":{
"region_id":[
32273
],
"boost":2
}
}
],
"must_not":[
],
"filter":[
]
}
},
"functions":[
{
"gauss":{
"location":{
"origin":{
"lat":"41.243368",
"lon":"-116.79711"
},
"offset":"0mi",
"scale":"100mi"
}
}
}
],
"score_mode":"sum",
"boost_mode":"sum"
}
}
}
}
The Bool Query has only a Should Clause.
Also, I am summing the scores, not multiplying them.
It's true that I do not have any items in the index that have the specified "region_id", but I fail to see how the results of the first query are excluded from the second query. It seems like the 0 score on the Bool Query is acting like a filter.

The first query acts as a match_all query so it returns everything and applies the function score.
In the second query you have a should clause, but since there are no must or filter clause it must match.
From ES docs: "In a boolean query with no must or filter clauses, one or more should clauses must match a document"

Related

Elasticsearch DSL query returning result for condition which isn't true

I want to have three conditions in my elasticsearch query and accordingly I have written as below. But I don't know why it is returning a DOCUMENT where AMOUNT is 250 and it EXISTS whereas my condition is ATLEAST one of the two i.e. AMOUNT less than or equal to zero or AMOUNT should not exist.
Below is the DSL Query
{
"from":0,
"size":10,
"track_total_hits":true,
"_source": ["amount", "npa_stageid_loanaccounts"],
"query":{
"bool":{
"must":[
{
"query_string":{
"default_field":"npa_stageid_loanaccounts.keyword",
"query":"Y"
}
},
{
"bool":{
"minimum_should_match":1,
"should":[
{
"range":{
"Amount":{
"lte":0
}
}
},
{
"bool":{
"must_not":[
{
"exists":{
"field":"Amount"
}
}
]
}
}
]
}
}
]
}
}
}
In your documents, you have amount but in your query you have Amount, the casing is not the same.

Elasticsearch query returning far less number of records

I am running following elasticsearch query from groovy script. There are thousands of records which meet this criteria, but I get only 10 records in return.
{
"query":{
"bool":{
"must":[
{
"match_all":{
}
},
{
"range":{
"#Timestamp":{
"gte":1417511269270,
"lte":1575277669270,
"format":"epoch_millis"
}
}
},
{
"match_phrase":{
"field1.keyword":{
"query":"value1"
}
}
},
{
"match_phrase":{
"field2.keyword":{
"query":"value2"
}
}
},
{
"range":{
"#Timestamp":{
"gte":"2001-03-01",
"lt":"2019-10-30"
}
}
}
],
"filter":[
],
"should":[
],
"must_not":[
]
}
}
}
What am I missing in my query?
You are missing a size parameter, which means it defaults to 10 results.
e.g. add this to your query object:
"size": 100

Can I alter the score of results based on a query within an Elasticsearch Aggregation?

I'm using an Elasticsearch filter aggregation with a nested top_hits aggregation to retrieve top matching documents based on different filters, but I can't seem to change the scores of results in each bucket via boosting or a nested function_score query. Is this just not possible? I haven't found any explicit documentation saying it won't work, and the query executes just fine, however the resulting scores aren't impacted.
Example query (note the huge boost in the first aggregation):
GET _search
{
"size":0,
"query":{
"bool":{
"should":[
{
"multi_match":{
"type":"phrase",
"query":"TV",
"fields":[
"categories^4"
]
}
}
]
}
},
"aggs":{
"1":{
"filter":{
"bool":{
"must":[
{
"multi_match":{
"type":"phrase",
"query":"Music",
"fields":[
"categories^10"
]
}
}
]
}
},
"aggs":{
"1_hits":{
"top_hits":{
"size":10,
"sort":[
{
"_score":{
"order":"desc"
}
}
]
}
}
}
},
"2":{
"filter":{
"bool":{
"must":[
{
"multi_match":{
"type":"phrase",
"query":"Music",
"fields":[
"categories"
]
}
}
]
}
},
"aggs":{
"2_hits":{
"top_hits":{
"size":10,
"sort":[
{
"_score":{
"order":"desc"
}
}
]
}
}
}
}
}
}

bool malformed query, expected END_OBJECT but found FIELD_NAME

I have some problem with the elasticsearch query. when I use the query code it feedback the messages [bool] malformed query, expected [END_OBJECT] but found [FIELD_NAME].
{
"from":0,
"size":15,
"query":{
"bool":{
"must":[
{
"multi_match":{
"query":"books",
"fields":[
"title^20",
"lead^10",
"content"
],
"type":"phrase"
}
}
]
},
"must":{
"match":{
"groupid":"599e4b49239cfa0a5a5f189d"
}
}
},
"sort":[
{
"times":{
"order":"desc"
}
}
]
}
Your second must clause is not properly located, it must be inside the existing bool/must query. You need to rewrite your query to this:
{
"from":0,
"size":15,
"query":{
"bool":{
"must":[
{
"multi_match":{
"query":"books",
"fields":[
"title^20",
"lead^10",
"content"
],
"type":"phrase"
}
},
{
"match":{
"groupid": "599e4b49239cfa0a5a5f189d"
}
}
]
}
},
"sort":[
{
"times":{
"order":"desc"
}
}
]
}

Combine two function_score queries in dis_max

I would like to make a query with two subqueries, each of them has it's own scoring based on function_score with script. For example, this subquery:
{
"query":{
"function_score":{
"query":{
"bool":{
"filter":[
{
"term":{
"rooms_count":3
}
},
{
"term":{
"addresses":"d76255c8-3173-4db5-a39b-badd3ebdf851"
}
},
{
"exists":{
"field":"zhk_id"
}
}
]
}
},
"script_score":{
"script":"1 * doc['price'].value/100000"
},
"boost_mode":"replace"
}
}
}
works fine, and it's score is based on price (about 190 points). But if I try to combine two subqueries in dis_max query, function_score is not working and I get scores about 1 point.
Explanation for each subquery looks like this
"value": 100.9416, "description": "script score function, computed with script:"[script: 1 * doc['price'].value/100000, type: inline, lang: null, params: {}]" and parameters:
{}",
for dis_max query like
"value": 1, "description": "ConstantScore(function score (#rooms_count: #addresses:d76255c8-3173-4db5-a39b-badd3ebdf851 #ConstantScore(fieldnames:zhk_id),function=script[script: 1 * doc['price'].value/100000, type: inline, lang: null, params: {}])), product of:",`
Can anybody tell me, how to combine function_score queries properly?
My full dis_max query on pastebin
Thanks to Daniel Mitterdorfer from https://discuss.elastic.co/t/combine-two-function-score-queries-in-dis-max/70666.
correct query is
{
"query":{
"dis_max":{
"queries":[
{
"function_score":{
"query":{
"bool":{
"filter":[
{
"term":{
"rooms_count":3
}
},
{
"term":{
"addresses":"d76255c8-3173-4db5-a39b-badd3ebdf851"
}
},
{
"missing":{
"field":"zhk_id"
}
}
]
}
},
"script_score":{
"script":"1 * doc['price'].value/100000"
},
"boost_mode":"replace"
}
},
{
"function_score":{
"query":{
"bool":{
"filter":[
{
"term":{
"rooms_count":3
}
},
{
"term":{
"addresses":"d76255c8-3173-4db5-a39b-badd3ebdf851"
}
},
{
"exists":{
"field":"zhk_id"
}
}
]
}
},
"script_score":{
"script":"1 * doc['price'].value/100000"
},
"boost_mode":"replace"
}
}
]
}
}
}

Resources