lovprogramming
lovprogramming

Reputation: 653

Elasticsearch - Boosting an individual term if it appears in the fields

I have the following search query that returns the documents that contain the word "apple", "mango" or "strawberry". Now I want to boost the scoring of the document whenever the word "cake" or "chips" (or both) is in the document (the word cake or chips doesn't have to be in the document but whenever it appears in "title" or "body" fields, the scoring should be boosted, so that the documents containing the "cake" or "chips" are ranked higher)

res = es.search(index='fruits', body={
    "query": {
        "bool": {
            "must": [
                {
                    "query_string": {
                        "query": "(apple) OR (mango) OR (strawberry)"
                    }
                },
                {
                    "bool": {
                        "must_not": [{
                            "match_phrase": {
                                "body": "Don't match this phrase."                     
                            }
                        }
                        ]
                    }
                }
            ]
        },
            "match": {
                "query": "(cake) OR (chips)",
                "boost": 2
                }
            }

    }
}) 

Any help would be greatly appreciated!

Upvotes: 2

Views: 857

Answers (1)

Kamal Kunjapur
Kamal Kunjapur

Reputation: 8840

Just include the values you would want to be boosted in a should clause as shown in the below query:

Query:

POST <your_index_name>/_search
{ 
   "query":{ 
      "bool":{ 
         "must":[ 
            { 
               "query_string":{ 
                  "query":"(apple) OR (mango) OR (strawberry)"
               }
            },
            { 
               "bool":{ 
                  "must_not":[ 
                     { 
                        "match_phrase":{ 
                           "body":"Don't match this phrase."
                        }
                     }
                  ]
               }
            }
         ],
         "should":[                                 <----- Add this
            { 
               "query_string":{ 
                  "query":"cake OR chips",
                  "fields": ["title","body"],       <----- Specify fields
                  "boost":10                        <----- Boost Field
               }
            }
         ]
      }
   }
}

Alternately, you can push your must_not clause to a level above in the query.

Updated Query:

POST <your_index_name>/_search
{ 
   "query":{ 
      "bool":{ 
         "must":[ 
            { 
               "query_string":{ 
                  "query":"(apple) OR (mango) OR (strawberry)"
               }
            }
         ],
         "should":[ 
            { 
               "query_string":{ 
                  "query":"cake OR chips", 
                  "fields": ["title","body"],
                  "boost":10
               }
            }
         ],
         "must_not":[                            <----- Note this
            { 
               "match_phrase":{ 
                  "body":"Don't match this phrase."
               }
            }
         ]
      }
   }
}

Basically should qualifies as logical OR while must is used as logical AND in terms of Boolean Operations.

In that way the query would boost the results or documents higher up the order as it would have higher relevancy score while the ones which only qualifies only under must would come with lower relevancy.

Hope this helps!

Upvotes: 2

Related Questions