Function_score using score_mode inside a bool query as max but working like sum? - elasticsearch

I am using function_score so that i can use its score_mode as maximum score of the bool query i am using actually i have two boolean query inside should now i want the score of the document to be the maximum score among both queries my code is given below but when i am passing a string for matching both then scores are being added not be taken maximum can anyone please tell me how can i acheive that.
"function_score": {
"boost_mode": "max",
"score_mode": "max",
"query": {
bool: {
"disable_coord": true,
"should": [
{
bool: {
"disable_coord": true,
"must": [
{
"constant_score": { // here i am using this because to remove tf/idf factors from my scoring
boost: 1.04,
"query": {
query_string: {
query: location_search,
fields: ['places_city.city'],
// boost: 1.04
}
}
}
}
]
}
},
{
"constant_score": { // here i am using this because to remove tf/idf factors from my scoring
boost: 1,
"query": {
"fuzzy_like_this" : {
"fields" : ["places_city.city"],
"like_text" : "bangaloremn",
"prefix_length": 3,
"fuzziness": 2
}
}
}
}
], "minimum_should_match": 1
}
}
}

Yes boolean query takes a sum by design. If you want the maximum score of two queries, you ought to look at the dismax query. Dismax is designed to pick a "winner".
Roughly speaking, this would look like
{"query":
"dismax": {
"queries": [
{ /* your first constant_score query above */},
{/* your second constant_score query from above */}
]
}
}
Unfortunately, function score query doesn't have a great way of operating on more than one text query at a time. See this question. If you want to do any complex math with the scores of multiple queries, Solr actually has a lot more flexibility in this area.

Related

What is the difference between should and boost final score calculation?

I'm a little confused about what is the difference between should and boost final score calculation
when a bool query has a must clause, the should clauses act as a boost factor, meaning none of them have to match but if they do, the relevancy score for that document will be boosted and thus appear higher in the result.
so,if we have:
one query which contains must and should clauses
vs
second query which contains must clause and boosting clause
Is there a difference ?
when you recommend to use must and should vs must and boosting clauses in a query ?
You can read the documentation of boolean query here, there is huge difference in the should and boost.
Should and must both contributes to the _score of the document, and as mentioned in the above documentation, follows the
The bool query takes a more-matches-is-better approach, so the score from each matching must or should clause will be added together to provide the final _score for each document.
While boost is a parameter, using which you can increase the weight according to your value, let me explain that using an example.
Index sample docs
POST _doc/1
{
"brand" : "samsung",
"name" : "samsung phone"
}
POST _doc/2
{
"brand" : "apple",
"name" : "apple phone"
}
Boolean Query using should without boost
{
"query": {
"bool": {
"should": [
{
"match": {
"name": {
"query": "apple"
}
}
},
{
"match": {
"brand": {
"query": "apple"
}
}
}
]
}
}
}
Search result showing score
"max_score": 1.3862942,
Now in same query use boost of factor 10
{
"query": {
"bool": {
"should": [
{
"match": {
"name": {
"query": "apple"
}
}
},
{
"match": {
"brand": {
"query": "apple",
"boost": 10 --> Note additional boost
}
}
}
]
}
}
}
Query result showing boost
"max_score": 7.624619, (Note considerable high score)
In short, when you want to boost a particular document containing your query term, you can additionally pass the boost param and it will be on top of the normal score calculated by should or must.

Elasticsearch Boolean query with Constant score wrapper

When using elasticsearch-7 I'm confused by es compound queries syntax.
Though reading es documents repeatedly but i just find standard syntax of Boolean or Constant score seperately.
As it illuminate,i understand what is 'query context' and what is 'filter context'.But when combining these two query type in a single query i don't know what it mean.
Let's see a example:
GET /classes_test/_search
{
"size": "21",
"query": {
"constant_score": {
"filter": {
"bool": {
"must": [
{
"match": {
"class_name": "29386556"
}
}
],
"should": [
{
"term": {
"master": "7033560"
}
},
{
"term": {
"assistant": "7033560"
}
},
{
"term": {
"students": "7033560"
}
}
],
"minimum_should_match": 1,
"must_not": [
{
"term": {
"class_id": 0
}
}
],
"filter": [
{
"term": {
"class_status": "1"
}
}
]
}
}
}
}
}
This query can be executed and response well.Each item in response content has a '_score' value with 1.0.
So,is it mean that the sub bool query as a entirety is in a filter context though it has a 'must' and 'should'?
Also i found boolean query can have a constant score sub query.
Why es allow these syntax but has no more words to explain?
If you use a constant_score query, you'll never get scores different than 1.0, unless you specify boost parameters in which case the score will match those.
If you need scoring you obviously need to ditch constant_score.
In your case, your match query on class_name cannot yield any other score than 1 or 0 since this is basically a yes/no filter, not a matching based on full-text search.
To sum up, all your query executes in a filter context (hence score 0 or 1) since you don't rely on full-text search. So you get scoring whenever you use full-text search, not because you use a match query. In your case, you can merge all must constraints into filter, it won't make any difference since you only have filters (yes/no matches) and no full-text search.

Add query time weight/boost based on field value

I'm currently using elasticsearch version 2.4 and wish to fine tune my result set based on a field I have called 'type' using query time boosting or weighting.
For example
If the value of the field 'type' is "Boats" add a weighting or boost of 4
If the value of the field 'type' is "Caravans" add a weighting or boost of 3
Thereforfor making boats that matched the query string appear before caravans in the search results.
I've found the documentation I've read so far very convoluted in regards to filters, functions and function scores. I'd appreciate if someone could provide an example to my scenario to get me going.
You should use the constant_score query and the boost option to prioritize.
{
"query": {
"bool": {
"should": [
{
"constant_score": {
"boost": 4,
"query": {
"match": {
"description": "Boats"
}
}
}
},
{
"constant_score": {
"boost": 3,
"query": {
"match": {
"description": "Caravans"
}
}
}
}
]
}
}
}

elasticsearch function score, boost weight of "number of matched terms in query" (coordination)

I want to use elasticsearch function score for customized scoring and these are my priorities for ranking:
number of common terms with query (for example a document which has 3 of 4 terms in query should be ranked higher than a document which has 2 of 4 terms in query, no matter how much is tf/idf score of each term). in elastic documentation it's called coordination factor.
sum of relevancy of terms. (tf/idf)
document popularity (number of votes for each document as described in boosting by popularity)
This is the body of request for elasticsearch currently used:
body = {
"query": {
"function_score": {
"query": {
{'match': {'text': query}}
},
"functions": [
{
"field_value_factor": {
"field": "ducoumnet_popularity",
}
}
],
}
}
}
Problem is that first priority is not satisfied with this request. for example there could be document A which has less common terms with query than document B, but because its common terms have more tf/idf score, document A is ranked higher than document B.
To prevent this I think the best way is to boost score of documents by coordination factor. is there any way to do this? something similar to this request:
body = {
"query": {
"function_score": {
"query": {
{'match': {'text': query}}
},
"functions": [
{
"field_value_factor": {
"field": "ducoumnet_popularity",
},
"field_value_factor": {
"field": "_coordination"
"weight": 10
}
}
],
}
}
}
I didn't find exact answer for this question but it may help someone to know that you can limit minimum precision for documents in result using minimum_should_match.
{
"query": {
"match": {
"content": {
"query": "quick brown dog",
"minimum_should_match": 75%
}
}
}
}
it accept many different configuration. more explanation:
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-minimum-should-match.html

In a should bool clause in elasticsearch what is default score mode?

Actually i am writing three query inside my should boo query clause in ES now i was wondering what is the default score_mode of the should clause as i want to use maximum of all three query score how can i achieve that. My query is given below now where to define score_mode ??
bool: {
"disable_coord": true,
"should": [
{
term : { 'address.area2' : search_area2 }
},
{
term : { "address.area1" : search_area1 }
},
{
term : { 'address.city' : search_city }
}
], "boost": 2.0
}
From the Bool Query docs:
The bool query takes a more-matches-is-better approach, so the score
from each matching must or should clause will be added together to
provide the final _score for each document.
To override that behavior, wrap your bool in a
Function Score Query. You can define a Field Value Factor Function for address.area2, one for address.area1 and one for address.city, then use max as score_mode.
The resulting function score should be something like the following (did not try, you may have to modify a bit)
"function_score": {
"query": YOUR_BOOL_QUERY,
"boost": 2,
"functions": [
{
"field_value_factor": {
"field": "address.area2",
"factor": 1
}
},
{
"field_value_factor": {
"field": "address.area1",
"factor": 1
}
},
{
"field_value_factor": {
"field": "address.city",
"factor": 1
}
}
],
"score_mode": "max",
"boost_mode": "replace"
}
UPDATE:
added "boost_mode": "replace" according to docs, because we want to ignore the query score and only use our function score

Resources