Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scoring by term position in ElasticSearch?

I'm implementing an auto-complete index in ElasticSearch and have run into an issue with sorting/scoring. Say I have the following strings in an index:

apple banana coconut donut
apple banana donut durian
apple donut coconut durian
donut banana coconut durian

When I search for "donut", I want the results to be ordered by the term location like so:

donut banana coconut durian
apple donut coconut durian
apple banana donut durian
apple banana coconut donut

I can't figure out how to make that happen. Term position isn't factored into the default scoring logic, and I can't find a way to get it in there. Seems like a simple enough issue though that others must have run into this before. Has anyone figured it out yet?

Thanks!

like image 632
IGx89 Avatar asked Dec 18 '14 03:12

IGx89


Video Answer


1 Answers

You can do a custom sorting, like this:

{
  "query": {
    "match": {
      "content": "donut"
    }
  },
  "sort": {
    "_script": {
      "script": "termInfo=_index['content'].get('donut',_OFFSETS);for(pos in termInfo){return _score+pos.startOffset};",
      "type": "number",
      "order": "asc"
    }
  }
}

In there I just returned the startOffset. If you need something else, play with those values and the original scoring and come up with a comfortable value for your needs.

Or you can do something like this:

{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "content": "donut"
        }
      },
      "script_score": {
        "script": "termInfo=_index['content'].get('donut',_OFFSETS);for(pos in termInfo){return pos.startOffset};"
      },
      "boost_mode": "replace"
    }
  },
  "sort": [
    {
      "_score": "asc"
    }
  ]
}

In either case you need in your mapping for that specific field to have this:

"content": {
  "type": "string",
  "index_options": "offsets"
}

meaning index_options needs to be set to offsets. Here more details about this.

like image 127
Andrei Stefan Avatar answered Sep 20 '22 20:09

Andrei Stefan