Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
PreferRecentFunctionScoreBuilder
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
2 / 2
5
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 append
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3namespace CirrusSearch\Search\Rescore;
4
5use CirrusSearch\SearchConfig;
6use Elastica\Query\FunctionScore;
7
8/**
9 * Builds a script score boost documents on the timestamp field.
10 * Can be initialized by config for full text and by special syntax in user query
11 */
12class PreferRecentFunctionScoreBuilder extends FunctionScoreBuilder {
13
14    /**
15     * @var float
16     */
17    private $halfLife;
18
19    /**
20     * @var float
21     */
22    private $decayPortion;
23
24    /**
25     * @param SearchConfig $config
26     * @param float $weight
27     * @param float $halfLife
28     * @param float $decayPortion
29     */
30    public function __construct( SearchConfig $config, $weight, $halfLife, $decayPortion ) {
31        parent::__construct( $config, $weight );
32        $this->halfLife = $halfLife;
33        $this->decayPortion = $decayPortion;
34    }
35
36    public function append( FunctionScore $functionScore ) {
37        if ( !( $this->halfLife > 0 && $this->decayPortion > 0 ) ) {
38            return;
39        }
40        // Convert half life for time in days to decay constant for time in milliseconds.
41        $decayConstant = log( 2 ) / $this->halfLife / 86400000;
42        $parameters = [
43            'decayConstant' => $decayConstant,
44            'decayPortion' => $this->decayPortion,
45            'nonDecayPortion' => 1 - $this->decayPortion,
46            'now' => time() * 1000,
47        ];
48
49        // e^ct where t is last modified time - now which is negative
50        $exponentialDecayExpression = "exp(decayConstant * (doc['timestamp'].value - now))";
51        if ( $this->decayPortion !== 1.0 ) {
52            $exponentialDecayExpression =
53                "$exponentialDecayExpression * decayPortion + nonDecayPortion";
54        }
55        $functionScore->addScriptScoreFunction( new \Elastica\Script\Script( $exponentialDecayExpression,
56            $parameters, 'expression' ), null, $this->weight );
57    }
58}