16

I would like to merge the rankings obtained from querying separate fields of an Elasticsearch index, so to obtain a "compound" ranking.

As a (silly) "matchmaking" example, suppose I wanted to retrieve best-matching results on an index of people containing their favorite music, food, sports.

The separate queries could be e.g.

"query": { "match" : { "music" : "indie classical metal" } }

which would yield me as ranked results:

  1. Alice, 2. Bob, 3. Charlie;

"query": { "match" : { "foods" : "falafel strawberries coffee" } }

yielding

  1. Alice, 2. Charlie, 3. Bob;

and

"query": { "match" : { "sports" : "basketball ski" } }

yielding

  1. Charlie, 2. Alice, 3. Bob.

Now, I would like to obtained an "aggregate" ranking based on the rankings above, e.g. using the voting methods listed in How to merge a collection of ordered preferences.

So far, to achieve something along these lines I used syntax for compound queries such as

"query": {
   "bool": {
        "should": [
                { "match" : { "music" : "indie classical metal" } },
                { "match" : { "foods" : "falafel strawberries coffee" } },
                { "match" : { "sports" : "basketball ski" } },
        ]
    }
 }

or

"query": {
   "dis_max": {
        "queries": [
                { "match" : { "music" : "indie classical metal" } },
                { "match" : { "foods" : "falafel strawberries coffee" } },
                { "match" : { "sports" : "basketball ski" } },
        ]
    }
 }

but (AFAIK) these don't do what I am looking for (which is not using scores, but ranks). I understand that's fairly straightforward to post-process the rankings (e.g. using elasticsearch-py and then a few Python lines), but is it possible to do the things above directly with an Elasticsearch query?

(bonus question: could you suggest alternative strategies to merge rankings from multiple fields, beyond bool+should and dis_max that I could try out?)

Davide Fiocco
  • 5,350
  • 5
  • 35
  • 72

1 Answers1

-1

Have a look at Function Score Query - it should allow you to do what you’re looking for. But be aware that it might result in slower query execution.

tine
  • 40
  • 1
  • 5
    You should probably provide a sample `function_score` query based on the OP's needs above. – Val May 24 '18 at 08:03