random_score does not work properly with "should" - elasticsearch

In the following code I always get "Alexander McQueen" products coming first, no matter what I set the seed to.
How can I change my search query to properly shuffle results?
{
"query": {
"function_score": {
"random_score": {
"seed": 99287
},
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"query_string": {
"query": "(adidas originals)",
"default_operator": "AND",
"fields": [
"name^4",
"description"
]
}
},
{
"terms": {
"category": [
"Fashion",
"Sports",
"Other",
""
]
}
},
{
"term": {
"currency": {
"term": "USD"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"query_string": {
"query": "(alexander mcqueen)",
"default_operator": "AND",
"fields": [
"name^4",
"description"
]
}
},
{
"terms": {
"category": [
"Fashion"
]
}
},
{
"term": {
"currency": {
"term": "USD"
}
}
}
]
}
}
]
}
}
}
},
"size": 40,
"from": 0
}

That's because the random score is being multiplied by the _score from the original query. If you want the results to be purely based on the random score, then set the boost_mode to replace (instead of the default multiply).
See the function_score documentation.

Related

Elasticsearch how to set different value with different scores for the same filed?

I have different type_id in an ES index , and want to give different value type_id different scores to make some type search result rank is higher .
My query is
{
"query":{
"bool":{
"must":[
{"terms":{"type_id":[9,10]}}
],
"should":[
{"match":{ "display_name":{"query":"keyword","boost":10}}},
{"match":{ "description":{"query":"keyword","boost":2}}}
]
}
}
}
I want to make type_id 9 match scores is higher than type_id 10 when display_name and description is same .
Please guide me in this problem.
Thanks.
You can group your queries like below and use boost to give more weightage to certain ids.
{
"query": {
"bool": {
"must": [
{
"bool": {
"minimum_should_match": 1,
"should": [
{
"term": {
"type_id": {
"value": 9,
"boost": 2
}
}
},
{
"term": {
"type_id": {
"value": 10,
"boost": 1
}
}
}
]
}
},
{
"bool": {
"minimum_should_match": 1,
"should": [
{
"match": {
"display_name": {
"query": "keyword",
"boost": 10
}
}
},
{
"match": {
"description": {
"query": "keyword",
"boost": 2
}
}
}
]
}
}
]
}
}
}
Edit: For query in comment , you can use function_score
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"function_score": {
"query": {
"bool": {
"must": [
{
"term": {
"type_id": {
"value": 9
}
}
}
],
"minimum_should_match": 1,
"should": [
{
"match": {
"display_name": {
"query": "keyword"
}
}
},
{
"match": {
"description": {
"query": "keyword"
}
}
}
]
}
},
"boost": "5"
}
},
{
"function_score": {
"query": {
"bool": {
"must": [
{
"term": {
"type_id": {
"value": 10
}
}
}
],
"minimum_should_match": 1,
"should": [
{
"match": {
"display_name": {
"query": "keyword"
}
}
},
{
"match": {
"description": {
"query": "keyword"
}
}
}
]
}
},
"boost": "4"
}
}
]
}
}
}

Elasticsearch - boosting specific documents in every search

I'm very new to Elasticsearch. I'm using it to filtering and also boosting some fields at query time. This is the code part for boosting and filtering:
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"multi_match": {
"type": "best_fields",
"query": "exampleKeyword",
"fields": [
"exampleField1^0",
"exampleField2^50",
"exampleField3^10",
"exampleField4^10",
"exampleField5^5"
],
"boost": 50
}
}]
}
}
],
"filter": [
{
"bool": {
"must": [
{
"bool": {
"must": [
{
"term": {
"bla": {
"value": ""
}
}
}
]
}
}, {
"term": {
"active": {
"value": "true"
}
}
},
{
"range": {
"closingDate": {
"gte": "201710310000",
"lte": "999912312359"
}
}
},
Now I want to boost some specific documents. I'll give an array of integers for example Field6 and if my search results contain the elements of the array, these documents should get boosted with, I dont know, 100 to my scale.
How can I do this? Finally I dont want to expand the result set. Just want to boost more the desired ids if results contain these ids.
Using function_score you can do something around these lines:
{
"query": {
"bool": {
"must": [
{
"function_score": {
"query": {
"bool": {
"should": [
{
"multi_match": {
"type": "best_fields",
"query": "bla",
"fields": [
"exampleField1^0",
"exampleField2^50",
"exampleField3^10",
"exampleField4^10",
"exampleField5^5"
],
"boost": 50
}
}
]
}
},
"functions": [
{
"filter": {
"ids": {
"values": [
1,
5
]
}
},
"weight": 10
}
],
"score_mode": "max",
"boost_mode": "multiply"
}
}
],
"filter": [
{
"bool": {
"must": [
{
"bool": {
"must": [
{
"term": {
"bla": {
"value": ""
}
}
}
]
}
},
{
"term": {
"active": {
"value": "true"
}
}
},
{
"range": {
"closingDate": {
"gte": "201710310000",
"lte": "999912312359"
}
}
}
]
}
}
]
}
}
}

Adding a condition to query

I have a query that works grate. How ever I need to add one condition.
I want to get a documents that also have the field "marked" :"true"
This is my query.
{
"from": 0,
"size": 100,
"min_score": 0.6,
"query": {
"bool": {
"should": [
{ "multi_match" : {
"fields" : ["_all"],
"query" : " Test " ,
"fuzziness" : "1.5" ,
"prefix_length" : "2"
}
}
],
"must": { "bool": { "must": [
{ "terms": { "language.id":["1"] }},
{ "term": { "forbidden":"false" }}
]
}}}
}, "sort": [{ "_score": { "order": "desc"}} ]
}
I have been trying ti add a should clause after both must clauses.
Where can I put this condition?
try this
{
"query": {
"bool": {
"should": [
{
"multi_match": {
"fields": [
"_all"
],
"query": " Test ",
"fuzziness": "1.5",
"prefix_length": "2"
}
}
],
"must": [
{
"terms": {
"language.id": [
"1"
]
}
},
{
"term": {
"forbidden": "false"
}
},
{
"term": {
"marked": "true"
}
}
]
}
}
}

ES Must match filter

I have this fairly simple es query and filter, using ES 2.3.5:
{
"query": {
"multi_match": {
"query": "image",
"fields": [
"ToRecipients"
"From",
"Subject"
]
}
},
"filter": {
"bool": {
"must": [
{
"match": {
"ToRecipients": "johndoe"
}
}
]
}
},
"sort": [
{
"DateTimeSent": {
"order": "desc"
}
}
]
}
For some reason it is not filtering by the ToRecipients field. The results coming back have all kinds of values for the field not just johndoe.
Where have I gone wrong?
Try this query instead:
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "image",
"fields": [
"ToRecipients",
"From",
"Subject"
]
}
}
],
"filter": {
"bool": {
"must": [
{
"match": {
"ToRecipients": "johndoe"
}
}
]
}
}
}
},
"sort": [
{
"DateTimeSent": {
"order": "desc"
}
}
]
}

Elasticsearch - Filtered query with weighted types

I have inherited an Elasticsearch query that I am trying to modify. The query I have at the moment is:
{
"fields": [
],
"from": 0,
"size": 51,
"query": {
"filtered": {
"query": {
"query_string": {
"fields": [
"data.*"
],
"default_operator": "AND",
"query": "*Search term*"
}
},
"filter": [
{
"terms": {
"type": [
"typeOne",
"typeTwo",
"typeThree"
]
}
}
]
}
}
}
Now what I have been trying to do is boost one of these terms over the other 2 in the results but have not been able to get it to work. I have tried adding a "boost" value but this has oddly given me the opposite effect - it disables any type that is given a boost.
I tried the following as the "filter" object:
"filter": [
{
"bool": {
"should": [
{
"term": {
"type": "typeOne"
}
},
{
"term": {
"type": "typeTwo"
}
},
{
"term": {
"type": "typeThree",
"boost": 2
}
}
]
}
}
]
But as I said before, instead of boosting "typeThree" it removes all "typeThree" from the results.
Can anyone help me boost a specific term type?
There are multiple ways to structure the query to achieve the above , one approach would be using function_score .It would look something on these lines
Example:
"query": {
"function_score": {
"functions": [
{
"filter": {
"term": {
"type": "typeThree"
}
},
"weight": 2
}
],
"score_mode": "sum",
"boost_mode": "sum",
"query": {
"filtered": {
"query": {
"query_string": {
"fields": [
"data.*"
],
"default_operator": "AND",
"query": "*search term*"
}
},
"filter": [
{
"terms": {
"type": [
"typeOne",
"typeTwo",
"typeThree"
]
}
}
]
}
}
}
}
You can enable explain to see how this affects the scoring
While keety's answer was 98% of the way there, it took a bit of extra googling to get it all together. The problem is that "weight" doesn't work here, instead you must use "boost_factor". The final query looks like this:
{
"fields": [
],
"from": 0,
"size": 51,
"query": {
"function_score": {
"functions": [
{
"filter": {
"term": {
"type": "typeOne"
}
},
"boost_factor": 1.2
},
{
"filter": {
"term": {
"type": "typeTwo"
}
},
"boost_factor": 1.1
},
{
"filter": {
"term": {
"type": "typeThree"
}
},
"boost_factor": 1
}
],
"score_mode": "sum",
"boost_mode": "sum",
"query": {
"filtered": {
"query": {
"query_string": {
"fields": [
"data.*"
],
"default_operator": "AND",
"query": "*search term*"
}
},
"filter": [
{
"terms": {
"type": [
"typeOne",
"typeTwo",
"typeThree"
]
}
}
]
}
}
}
}
}

Resources