Am trying to boost records with a particular date in the future closest to now towards the top of the results, and make those with dates in the past less relevant. I've seen a number of posts about how to boost results which are just closer to now, but that's not really what I need.
-
So, the closer the dates are to `NOW`, but still in the future, they are great. But as soon as `NOW` is passed, they shall be at the end of the list? – cheffe Jan 23 '14 at 17:55
-
Kind of, but more like first comes dates in the future prioritized closer to `NOW`, then dates in the past prioritized closer to `NOW`. – Greg Hinch Jan 24 '14 at 09:55
-
So, if say `NOW=2012-12-30` and there are the dates `A=2012-12-31`, `B=2012-12-29` and `C=2013-01-30`, then the score of A shall be better than the of B. But what about the score of C, better than the one of B? Could you give a more detailed example in your question? – cheffe Jan 24 '14 at 10:16
-
In this case, the preferred order would be `A, C, B` – Greg Hinch Jan 24 '14 at 10:28
-
Further, let's add `D=2012-11-30` and `E=2012-12-01`. The preferred order would be `A,C,B,E,D` – Greg Hinch Jan 24 '14 at 10:30
2 Answers
What you want to do is:
- Know if the date is in the future or the past
- Use different boost functions for each case
Assuming the field name is due_date, we'll start building your query.
First, you want to get the time difference.
&timediff=ms(due_date,NOW)
You can use NOW/HOUR, NOW/DAY for better performance
Second, we need to know if duration is positive or negative: adding a number to its absolute value will return 1/true on positive and 0/false on negative.
&future=sum($timediff,abs($timediff)
Now depending whether the number is positive or negative you want to apply different boost functions. You can use any function you want here.
&futureboost=recip($timediff,1,36000000,36000000)
&pastboost=recip($timediff,1,3600000,3600000)
$finalboost=if($future,$futureboost,$pastboost)
&boost=$finalboost
Notice that futureboost parameters are 10x more than pastboost which will give higher boost to future documents than past ones. The recip function is documented on the Solr Function Query page and you can tune the parameters of both futureboost and pastboost functions to your case.
To return the function value, you can use:
&fl=_DATE_BOOST_:$finalboost
Full Query will be a combination of all the above:
&timediff=ms(due_date,NOW/HOUR)
&future=sum($timediff,abs($timediff)
&futureboost=recip($timediff,1,36000000,36000000)
&pastboost=recip($timediff,1,3600000,3600000)
$finalboost=if($future,$futureboost,$pastboost)
&boost=$finalboost
&fl=_DATE_BOOST_:$finalboost

- 2,171
- 21
- 27
-
This effectively covers it. I had to modify a bit to add a second diff for past dates, `&pastdiff=ms(NOW/HOUR,due_date)&pastboost=recip($pastdiff,1,360000,3600000)` because using the other one would be negative. Could also use `abs` there I suppose. Sadly using `if` requires Solr 4 which isn't yet an option for us in production, but I don't see any other way to do this as effectively you must do an `if` check to query correctly – Greg Hinch Jan 31 '14 at 14:12
Solved it by applying the below boost query :
bq=movie_release_date:[NOW/DAY-1MONTH TO NOW/DAY+2MONTHS]^10
Not that accurate as the previous answer, but in case you lack Solr 4, it results pretty much the same.

- 65
- 3