protected function getResultScore($result)
{
$output = [];
$corpus = $this->buildResultIndex($result);
$count = count($corpus['count']);
// This block iterates the search query words and checks both their
// existence and frequency in the index.
//
// The score is passed through log(x, 2) to reduce the smooth the difference.
//
foreach ($this->searchWords as $word) {
$word = mb_strtolower($word);
if (isset($corpus['dictionary'][$word])) {
$entry = $corpus['dictionary'][$word];
foreach ($entry['postings'] as $field => $posting) {
//get term frequency–inverse document frequency
$score = $posting['frequency'] * log($count + 1 / $entry['frequency'] + 1, 2);
if (isset($output[$field])) {
$output[$field] += $score;
} else {
$output[$field] = $score;
}
}
}
}
// length normalise, we do this to stop smaller amounts of text having
// a disproportionate effect on the score.
foreach ($output as $field => $score) {
$output[$field] = $score / $corpus['count'][$field];
}
// Finally this weights by using the field specific weighting value that
// is set inside `contenttypes.yml` This uses a weighting factor from 0 to
// 100 that alters the score accordingly.
$weights = $this->getContentFields();
foreach ($output as $field => &$score) {
if (isset($weights[$field]['weight'])) {
$multiplier = $weights[$field]['weight'] / 100;
if ($multiplier > 0) {
$score = $score * $multiplier;
}
}
}
return array_sum($output);
}