Search code examples
ruby-on-railsrubyelasticsearchsearchkicksolr-boost

Searchkick: Boosting future dates


I'm using Searchkick in a Rails project with an ElasticSearch 6.8 server. I'm trying to boost certain documents that have a year field that's equal to this year or a year in the future.

I've tried using boost_where and most recently boost_by but neither work. boost_by generates a function_score function that errors out in ElasticSearch. Here's my most recent try.

Model.search('value', boost_by: { year: { scale: '5y' } })

ElasticSearch seems to dislike the calendar interval (5y) even though this should be valid. Here's the reason object from the error:

          "caused_by": {
            "type": "number_format_exception",
            "reason": "For input string: \"5y\""
          }

I've tried setting origin and decay along with scale but that doesn't seem to help anything.

Here is the query generated by Searchkick (model and field names changed due to a very specific domain model).

  Model Search (163.5ms)  model_development/_search {"query":{"function_score":{"functions":[{"weight":1,"gauss":{"year":{"scale":"5y"}}}],"query":{"bool":{"should":[{"dis_max":{"queries":[{"multi_match":{"query":"Abreu","boost":10,"operator":"and","analyzer":"searchkick_search","fields":["*.analyzed"],"type":"best_fields"}},{"multi_match":{"query":"Abreu","boost":10,"operator":"and","analyzer":"searchkick_search2","fields":["*.analyzed"],"type":"best_fields"}},{"multi_match":{"query":"Abreu","boost":1,"operator":"and","analyzer":"searchkick_search","fuzziness":1,"prefix_length":0,"max_expansions":3,"fuzzy_transpositions":true,"fields":["*.analyzed"],"type":"best_fields"}},{"multi_match":{"query":"Abreu","boost":1,"operator":"and","analyzer":"searchkick_search2","fuzziness":1,"prefix_length":0,"max_expansions":3,"fuzzy_transpositions":true,"fields":["*.analyzed"],"type":"best_fields"}}]}}]}},"score_mode":"sum"}},"timeout":"11s","_source":false,"size":10000}

Solution

  • Year is likely not a supported date format due to it not having an absolute representation. One day is always 24 hours, but one year is sometimes 364 days and usually 365 days. Rather than solve for this complexity, ES likely stops at days.

    If you want, you can instead use days for your scale:

    Model.search('value', boost_by: { year: { scale: '1825d' } })