Skip to content

Commit

Permalink
#37 Adds a weight multiplier to generate a value for the Solr "pf" re…
Browse files Browse the repository at this point in the history
…quest parameter that's used when matching phrases
  • Loading branch information
extracts committed Dec 1, 2023
1 parent e0593c0 commit 357b053
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 9 deletions.
45 changes: 36 additions & 9 deletions src/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
* @method $this addFields( string $fields )
* @method $this addSort( $sorting )
* @method $this setWeightedFields( int[] $weightedFields ) assigns boost factors to fields (e.g. [ 'title' => 10, 'abstract' => 0.5 ])
* @method $this setWeightMultiplier( int $multiplier ) multiplier to further increase boost factors when matching phrases
*/
class Query
{
Expand All @@ -99,15 +100,16 @@ class Query
public function reset()
{
$this->data = [
'start' => null,
'rows' => null,
'fields' => null,
'sort' => null,
'union' => false,
'filter' => null,
'facet' => null,
'subfilters' => null,
'weightedfields' => null,
'start' => null,
'rows' => null,
'fields' => null,
'sort' => null,
'union' => false,
'filter' => null,
'facet' => null,
'subfilters' => null,
'weightedfields' => null,
'weightmultiplier' => null,
];
}

Expand Down Expand Up @@ -242,6 +244,30 @@ public function getWeightedFields()
return $this->data['weightedfields'];
}

/**
* Returns a positive integer used as a multiplier to further increase field-specific boost factors when
* matching phrases (i.e., in cases where all query terms appear in close proximity.
*
* For example, with a weight multiplier of 5, the weightedfields array [ 'title' => 10, 'abstract' => 0.5 ]
* would be translated to [ 'title' => 50, 'abstract' => 2.5 ] when matching phrases.
*
* @return int
*/
public function getWeightMultiplier()
{
if ($this->data['weightmultiplier'] === null) {
$config = Config::get();

if (isset($config->search->weightMultiplier)) {
$this->data['weightmultiplier'] = $config->search->weightMultiplier;
} else {
$this->data['weightmultiplier'] = 1;
}
}

return $this->data['weightmultiplier'];
}

/**
* Retrieves value of selected query parameter.
*
Expand Down Expand Up @@ -272,6 +298,7 @@ public function set($name, $value, $adding = false)
switch ($name) {
case 'start':
case 'rows':
case 'weightmultiplier':
if ($adding) {
throw new InvalidArgumentException('invalid parameter access on ' . $name);
}
Expand Down
23 changes: 23 additions & 0 deletions src/Solr/Solarium/Adapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,12 @@ protected function applyParametersOnQuery(
if (! empty($weightedFields)) {
$queryFields = $this->getQueryFieldsString($weightedFields);
$edismax->setQueryFields($queryFields);

$weightMultiplier = $parameters->getWeightMultiplier();
if ($weightMultiplier !== null) {
$phraseFields = $this->getPhraseFieldsString($weightedFields, $weightMultiplier);
$edismax->setPhraseFields($phraseFields);
}
}
}

Expand Down Expand Up @@ -911,4 +917,21 @@ protected function getQueryFieldsString($weightedFields)

return implode(' ', $queryFields);
}

/**
* Generates a phrase fields string that can be used as input for the Solr `pf` request parameter.
*
* @param int[] $weightedFields assigns boost factors to fields, e.g.: [ 'title' => 10, 'abstract' => 0.5 ]
* @param int $weightMultiplier factor by which each boost factor will be multiplied when matching phrases, e.g.: 5
* @return string phrase fields string, e.g.: "title^50 abstract^2.5"
*/
protected function getPhraseFieldsString($weightedFields, $weightMultiplier)
{
$phraseFields = [];
foreach ($weightedFields as $field => $boostFactor) {
$phraseFields[] = "$field^" . $boostFactor * $weightMultiplier;
}

return implode(' ', $phraseFields);
}
}

0 comments on commit 357b053

Please sign in to comment.