View source
<?php
namespace Drupal\search_api_solr\Plugin\search_api\processor;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\search_api\Plugin\PluginFormTrait;
use Drupal\search_api\Processor\ProcessorPluginBase;
use Drupal\search_api\Query\QueryInterface;
use Drupal\search_api_solr\SolrBackendInterface;
class BoostMoreRecent extends ProcessorPluginBase implements PluginFormInterface {
use PluginFormTrait;
protected static $boost_factors = [
'0.0' => '0.0',
'0.1' => '0.1',
'0.2' => '0.2',
'0.3' => '0.3',
'0.5' => '0.5',
'0.8' => '0.8',
'1.0' => '1.0',
'2.0' => '2.0',
'3.0' => '3.0',
'5.0' => '5.0',
'8.0' => '8.0',
'13.0' => '13.0',
'21.0' => '21.0',
];
public function defaultConfiguration() {
return [
'boosts' => [],
];
}
public function buildConfigurationForm(array $form, FormStateInterface $formState) {
foreach ($this->index
->getFields(TRUE) as $field_id => $field) {
if ('date' === $field
->getType()) {
$form['boosts'][$field_id] = [
'#type' => 'details',
'#title' => $field
->getLabel(),
];
$form['boosts'][$field_id]['boost'] = [
'#type' => 'select',
'#title' => $this
->t('Boost'),
'#options' => static::$boost_factors,
'#description' => $this
->t('To boost more recent dates, Solr performs a reciprocal function with recip(x,m,a,b) implementing a/(m*x+b) where m,a,b are constants, and x is a date converted into the difference between NOW and its timestamp using a configurable resolution. When a and b are equal, and x>=0, this function has a maximum value of 1 that drops as x increases. Increasing the value of a and b together results in a movement of the entire function to a flatter part of the curve. These properties make this an ideal function for boosting more recent documents. Therefore its result is multiplied with a configurable boost factor. Setting it to 0.0 disables the boost by recent date for this field.'),
'#default_value' => sprintf('%.1F', $this->configuration['boosts'][$field_id]['boost'] ?? 0.0),
];
$form['boosts'][$field_id]['resolution'] = [
'#type' => 'select',
'#title' => $this
->t('Resolution'),
'#options' => [
'NOW' => $this
->t('milliseconds'),
'NOW/SECOND' => $this
->t('seconds'),
'NOW/MINUTE' => $this
->t('minutes'),
'NOW/HOUR' => $this
->t('hours'),
'NOW/DAY' => $this
->t('days'),
'NOW/WEEK' => $this
->t('weeks'),
'NOW/MONTH' => $this
->t('months'),
'NOW/YEAR' => $this
->t('years'),
],
'#default_value' => $this->configuration['boosts'][$field_id]['resolution'] ?? 'NOW',
];
$form['boosts'][$field_id]['m'] = [
'#type' => 'textfield',
'#title' => $this
->t('Constant m'),
'#default_value' => $this->configuration['boosts'][$field_id]['m'] ?? '3.16e-11',
];
$form['boosts'][$field_id]['a'] = [
'#type' => 'number',
'#step' => 0.01,
'#title' => $this
->t('Constant a'),
'#default_value' => $this->configuration['boosts'][$field_id]['a'] ?? 0.1,
];
$form['boosts'][$field_id]['b'] = [
'#type' => 'number',
'#step' => 0.01,
'#title' => $this
->t('Constant b'),
'#default_value' => $this->configuration['boosts'][$field_id]['b'] ?? 0.05,
];
}
}
return $form;
}
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$values = $form_state
->getValues();
foreach ($values['boosts'] as $field_id => $boost) {
if (0 == $boost['boost']) {
unset($values['boosts'][$field_id]);
}
}
$form_state
->setValues($values);
$this
->setConfiguration($values);
}
public function preprocessSearchQuery(QueryInterface $query) {
parent::preprocessSearchQuery($query);
$boosts = $query
->getOption('solr_document_boost_factors', []);
foreach ($this->configuration['boosts'] as $field_id => $boost) {
$boosts[$field_id] = sprintf('product(%.1F,recip(ms(%s,%s),%s,%.3F,%3F))', $boost['boost'], $boost['resolution'], SolrBackendInterface::FIELD_PLACEHOLDER, $boost['m'], $boost['a'], $boost['b']);
}
if ($boosts) {
$query
->setOption('solr_document_boost_factors', $boosts);
}
}
}