Help with function_score


(Alkalit) #1

I need to tune search relevance for ads. In the project we are not deleting ads in time.
But we need to show up more-or-less fresh ads for users. So I decided to use the function_score query.
But it does not works - relevance is changing, but actually I'm getting the same result every time.

I tried to choose different values for the function, but did not notice the difference.

The request:

curl -XGET 'http://localhost:9200/_search?pretty' -d '{
 "from": 0,
 "query": {
   "filtered": {
     "filter": {
       "missing": {
         "field": "deleted_at"
       }
     },
     "query": {
       "bool": {
         "must": [
           {
             "range": {
               "created_at": {
                 "lt": "2016-11-18T14:27:30.524856+00:00"
               }
             }
           },
           {
             "term": {
               "ad_type": "sell"
             }
           },
           {
             "function_score": {
               "functions": [
                 {
                   "linear": {
                     "updated_at": {
                       "decay": 0.3,
                       "offset": "1w",
                       "scale": "4w"
                     }
                   }
                 }
               ]
             }
           },
           {
             "match": {
               "text": "\u0431\u0438\u0433 \u0431\u0435\u0433\u0438"
             }
           }
         ]
       }
     }
   }
 },
 "size": 20
}'

The mapping: http://pastebin.com/hnvgVyKS
ES version is 2.3


(Abdon Pijpelink) #2

There are a few things that stand out with your query.

  • The filtered_query that you are using is deprecated in Elasticsearch version 2.0 and is not supported for version 5.0 .This is probably a good time to put your filters inside of the bool query instead.
  • The ad_type field on which you are doing a term query is analyzed using the russian analyzer. You probably want to make it a not_analyzed field if you are using it for term queries?
  • You have put the range query on the created_at field and the term query on the ad_type field inside of the must clause of your bool query. Things that you put inside of a must clause will contribute to the score that's calculated for your documents when you query them. In the case of these range and term queries, the score will be 1 if a document matches or 0 if it doesn't match. However, it probably doesn't make sense that you score on these clauses? Either a document is in this range and matches the ad_type or it doesn't. These two clauses should not contribute to the score. So, I'd recommend that you put them in a filter clause instead.

My first step would be to clean up the query along the points that I raised above. It will give you a better score, and a score that's easier to understand. If you still have problems after doing so, let me know and I'd be happy to delve deeper.

By the way, do you know about the explain API? It will explain in great detail how a score is calculated.


(Alkalit) #3

Thanks alot for your response. I'm sorry for I could not replay earlier.

You probably want to make it a not_analyzed field if you are using it for term queries?

Yes, you are absolutly correct. It's my mistake with the mapping.

After some searches and experiments I got something like this:

{
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "filter": [
              {
                "missing": {
                  "field": "deleted_at"
                }
              },
              {
                "range": {
                  "created_at": {
                    "lt": "now"
                  }
                }
              },
              {
                "term": {
                  "ad_type": "sell"
                }
              }
            ]
          }
        },
        {
          "function_score": {
            "functions": [
              {
                "exp": {
                  "updated_at": {
                    "decay": 0.33,
                    "scale": "12w"
                  }
                }
              }
            ],
            "query": {
              "match": {
                "text": "search phrase"
              }
            }
          }
        }
      ]
    }
  },
}

(system) #4

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.