elasticsearchsolr-boost

elasticsearch boost query in feild having multiple value


I have some document in elasticsearch index. Here is the sample document

DOC1

{
"feild1":["hi","hello","goodmorning"]
"feild2":"some string"
"feild3":{}
}

DOC2

{
"feild1":["hi","goodmorning"]
"feild2":"some string"
"feild3":{}
}

DOC3

{
"feild1":["hi","hello"]
"feild2":"some string"
"feild3":{}
}

I want to query for feild1 having values "hi" and "hello" if both is present then that document should come first if any one is present then it should come after that. for example: result should be in order of DOC1, DOC3, DOC2. I tried with boost query. but it is retuning not in the order that I want. Here is the query that I am trying.

{
    "query": {
        "bool": {
            "must": [
                {
                    "match_phrase": {
                       "avail_status": true
                    }
                },
               {
                   "bool": {
                       "should": [
                          {
                               "constant_score": {
                                  "filter": {
                                  "terms": {
                                     "feild1": [
                                        "hi"
                                     ]
                                  }
                                  },
                                  "boost": 20
                               }
                           },
                           {
                               "constant_score": {
                                  "filter": {
                                  "terms": {
                                     "feild1": [
                                        "hello"
                                     ]
                                  }
                                  },
                                  "boost": 18
                               }
                           }
                       ]
                   }
               }
            ]
        }
    }
}

this is returning me first those document having "hi" and then those having "hello". Thanks in advance!


Solution

  • To add extra boost for documents with larger field1, you can put funtion_score script score.

    Mappings

    {
      "mappings": {
        "document_type" : {
          "properties": {
            "field1" : {
              "type": "text",
              "fielddata": true
            },
            "field2" : {
              "type": "text"
            },
            "field3" : {
              "type": "text"
            }
          }
        }
      }
    }
    

    Index documents

    POST custom_score_index1/document_type
    
    {
    "feild1":["hi","hello","goodmorning"],
    "feild2":"some string",
    "feild3":{}
    }
    
    POST custom_score_index1/document_type
    
    {
    "feild1":["hi","goodmorning"],
    "feild2":"some string",
    "feild3":{}
    }
    
    POST custom_score_index1/document_type
    
    {
    "feild1":["hi","hello"],
    "feild2":"some string",
    "feild3":{}
    }
    

    Query with function score add extra _score for larger size for field1

    POST custom_score_index1/document_type/_search
    {
        "query": {
            "function_score": {
                "query": {
                    "bool": {
                        "must": [{
                                "match_phrase": {
                                    "avail_status": true
                                }
                            },
                            {
                                "bool": {
                                    "should": [{
                                            "constant_score": {
                                                "filter": {
                                                    "terms": {
                                                        "feild1": [
                                                            "hi"
                                                        ]
                                                    }
                                                },
                                                "boost": 20
                                            }
                                        },
                                        {
                                            "constant_score": {
                                                "filter": {
                                                    "terms": {
                                                        "feild1": [
                                                            "hello"
                                                        ]
                                                    }
                                                },
                                                "boost": 18
                                            }
                                        }
                                    ]
                                }
                            }
                        ]
                    }
                },
                "functions": [{
                    "script_score": {
                        "script": {
                            "inline": "_score + 10000 * doc['field1'].length"
                        }
                    }
                }],
                "score_mode": "sum",
                "boost_mode": "sum"
            }
        }
    }