function SearchIndex::updateWordWeights

Same name and namespace in other branches
  1. 9 core/modules/search/src/SearchIndex.php \Drupal\search\SearchIndex::updateWordWeights()
  2. 8.9.x core/modules/search/src/SearchIndex.php \Drupal\search\SearchIndex::updateWordWeights()
  3. 10 core/modules/search/src/SearchIndex.php \Drupal\search\SearchIndex::updateWordWeights()
1 call to SearchIndex::updateWordWeights()
SearchIndex::index in core/modules/search/src/SearchIndex.php

File

core/modules/search/src/SearchIndex.php, line 261

Class

SearchIndex
Provides search index management functions.

Namespace

Drupal\search

Code

public function updateWordWeights(array $words) {
    try {
        // Update word IDF (Inverse Document Frequency) counts for new/changed
        // words.
        $words = array_keys($words);
        foreach ($words as $word) {
            // Get total count.
            $total = $this->replica
                ->query("SELECT SUM([score]) FROM {search_index} WHERE [word] = :word", [
                ':word' => $word,
            ])
                ->fetchField();
            // Apply Zipf's law to equalize the probability distribution.
            $total = log10(1 + 1 / max(1, $total));
            $this->connection
                ->merge('search_total')
                ->key('word', $word)
                ->fields([
                'count' => $total,
            ])
                ->execute();
        }
        // Find words that were deleted from search_index, but are still in
        // search_total. We use a LEFT JOIN between the two tables and keep only
        // the rows which fail to join.
        $result = $this->replica
            ->query("SELECT [t].[word] AS [realword], [i].[word] FROM {search_total} [t] LEFT JOIN {search_index} [i] ON [t].[word] = [i].[word] WHERE [i].[word] IS NULL");
        $or = $this->replica
            ->condition('OR');
        foreach ($result as $word) {
            $or->condition('word', $word->realword);
        }
        if (count($or) > 0) {
            $this->connection
                ->delete('search_total')
                ->condition($or)
                ->execute();
        }
    } catch (\Exception $e) {
        throw new SearchIndexException("Failed to update totals for index words.", 0, $e);
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.