How do you multiply two query's relevance scores in Elasticsearch?


(Doug Turnbull) #1

Related to this Stackoverflow Question.

Elasticsearch has a pretty powerful and intuitive Query DSL. However, I've think I've hit a functionality wall in one respect. In Solr, you can run arbitrary queries in function queries, then combine them with arbitrary math. For example, in Solr you can specify queries and give them names, like

queryCat={!lucene df=text v=$q}cat
queryDog={!lucene df=text v=$q}dog
bf=product(query($queryCat),query($queryDog))

Those not familiar with Solr's odd and admittedly hard to read DSL, this is a bit analogous to creating two match queries, one matching the term cat in the field text, the other looking for dog in the field text. Solr lets you assign these names to use later. Here in a bf (additive boost function, like an additive function_score query), the product of the two relevance scores are being used as an additive boost.

Now it appears that with function_score queries you can introduce a single query, and perform arbitrary math on the _score variable associated with that query's score. You can also use any number of filters to control when functions are applied, but you can't do anything with any secondary relevance score or query. There's tremendous flexibility in Elasticsearch's function_score query, up to being able to build very sophisticated functions. Yet it feels like its missing something not being able to run additional sub queries to ask additional questions of the index.

What I'd like though is to work with two relevance scores at once in a function_score query. As if there were a _score1 or _score2 or something. For instance, if somehow the following were possible, it would help some (though its not quite arbitrary math)

"function_score": {
   "query": {
       "match": {
          "text": "cat"
       }
   },
   functions: [
      "query": {
          "match": {
             "text": "dog"
          }
      }
   ]
}

Of course that's not correct. It's entirely possible I'm missing something , and there's an obvious way to achieve what I want. So hopefully someone helpful/smart in the community can point that out to me :smile:

Thanks!


(system) #2