You are here

protected function FuzzySearchService::indexItem in Fuzzy Search 7

Helper method to index a given item.

Parameters

SearchApiIndex $index: The search index for which the item should be indexed.

int|string $id: Item ID.

array $item: Associative array containing information about the item to be indexed:

  • type: One of the data types recognized by the Search API, or the special type "tokens" for fulltext fields.
  • original_type: The original type of the property, as defined by the datasource controller for the index's item type.
  • value: The value to index.

Return value

bool TRUE on success, FALSE otherwise.

Throws

Exception If indexing was prevented by a fundamental configuration error.

1 call to FuzzySearchService::indexItem()
FuzzySearchService::indexItems in includes/service.inc
Indexes the specified items.

File

includes/service.inc, line 400

Class

FuzzySearchService
Search service class using the database for storing index information.

Code

protected function indexItem(SearchApiIndex $index, $id, array $item) {
  $fields = $this->options['indexes'][$index->machine_name];
  $txn = db_transaction('search_api_indexing', $this->queryOptions);
  try {
    foreach ($item as $name => $field) {
      $table = $fields[$name]['table'];
      $boost = $fields[$name]['boost'];
      db_delete($table, $this->queryOptions)
        ->condition('item_id', $id)
        ->execute();
      $type = $field['type'];
      $value = $this
        ->convert($field['value'], $type, $field['original_type'], $index);
      $word_id = NULL;
      if (search_api_is_text_type($type, array(
        'text',
        'tokens',
      ))) {
        $words = array();
        foreach ($value as $token) {

          // Taken from core search to reflect less importance of words later
          // in the text.
          // Focus is a decaying value in terms of the amount of unique words
          // up to this point. From 100 words and more, it decays, to e.g. 0.5
          // at 500 words and 0.3 at 1000 words.
          $focus = min(1, 0.01 + 3.5 / (2 + count($words) * 0.015));
          $value =& $token['value'];
          if (is_numeric($value)) {
            $value = ltrim($value, '-0');
          }
          elseif (drupal_strlen($value) < $this->options['min_chars']) {
            continue;
          }
          $value = drupal_strtolower($value);
          $token['score'] *= $focus;
          if (!isset($words[$value])) {
            $words[$value] = $token;
          }
          else {
            $words[$value]['score'] += $token['score'];
          }
        }
        if ($words) {
          $query = db_insert($table, $this->queryOptions)
            ->fields(array(
            'item_id',
            'word_id',
            'ngram',
            'completeness',
            'score',
          ));
          foreach ($words as $word) {

            // Don't index if not preprocessed by fuzzysearch.
            if (!isset($word['ngrams'])) {
              continue;
            }
            if (!isset($word_id)) {
              $word_id = fuzzysearch_get_word_id($table);
            }
            foreach ($word['ngrams'] as $ngram) {
              $query
                ->values(array(
                'item_id' => $id,
                'word_id' => $word_id,
                'ngram' => $ngram,
                'completeness' => $word['completeness'],
                'score' => $word['score'] * $boost,
              ));
            }
            $word_id = $query
              ->execute();
          }
        }
      }
      elseif (search_api_is_list_type($type)) {
        $values = array();
        if (is_array($value)) {
          foreach ($value as $v) {
            if ($v !== NULL) {
              $values[$v] = TRUE;
            }
          }
          $values = array_keys($values);
        }
        else {
          $values[] = $value;
        }
        if ($values) {
          $insert = db_insert($table, $this->queryOptions)
            ->fields(array(
            'item_id',
            'value',
          ));
          foreach ($values as $v) {
            $insert
              ->values(array(
              'item_id' => $id,
              'value' => $v,
            ));
          }
          $insert
            ->execute();
        }
      }
      else {
        db_insert($table, $this->queryOptions)
          ->fields(array(
          'item_id' => $id,
          'value' => $value,
        ))
          ->execute();
      }
    }
  } catch (Exception $e) {
    $txn
      ->rollback();
    throw $e;
  }
  return TRUE;
}