protected function SearchApiDbService::indexItem in Search API Database Search 7
Indexes a single item on the specified index.
Used as a helper method in indexItems().
Parameters
SearchApiIndex $index: The index for which the item is being indexed.
$id: The item's ID.
array $item: The extracted fields of the item.
Throws
Exception Any encountered database (or other) exceptions are passed on, out of this method.
1 call to SearchApiDbService::indexItem()
- SearchApiDbService::indexItems in ./
service.inc - Indexes the specified items.
File
- ./
service.inc, line 850 - Contains SearchApiDbService.
Class
- SearchApiDbService
- Indexes and searches items using the database.
Code
protected function indexItem(SearchApiIndex $index, $id, array $item) {
$fields = $this
->getFieldInfo($index);
$fields_updated = FALSE;
$txn = $this->connection
->startTransaction('search_api_indexing');
try {
$inserts = array();
$text_inserts = array();
foreach ($item as $name => $field) {
// Sometimes index changes are not triggering the update hooks
// correctly. Therefore, to avoid DB errors, we re-check the tables
// here before indexing.
if (empty($fields[$name]['table']) && !$fields_updated) {
unset($this->options['indexes'][$index->machine_name][$name]);
$this
->fieldsUpdated($index);
$fields_updated = TRUE;
$fields = $this->options['indexes'][$index->machine_name];
}
if (empty($fields[$name]['table'])) {
watchdog('search_api_db', "Unknown field !field: please check (and re-save) the index's fields settings.", array(
'!field' => $name,
), WATCHDOG_WARNING);
continue;
}
$table = $fields[$name]['table'];
$boost = $fields[$name]['boost'];
$this->connection
->delete($table)
->condition('item_id', $id)
->execute();
// Don't index null values
if ($field['value'] === NULL) {
continue;
}
$type = $field['type'];
$value = $this
->convert($field['value'], $type, $field['original_type'], $index);
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));
$token_value =& $token['value'];
$token_value = trim(preg_replace('/[\\pZ\\pC]+/u', ' ', $token_value));
if (is_numeric($token_value)) {
$token_value = ltrim($token_value, '-0');
}
elseif (drupal_strlen($token_value) < $this->options['min_chars']) {
continue;
}
$token_value = drupal_strtolower($token_value);
$token['score'] *= $focus;
if (!isset($words[$token_value])) {
$words[$token_value] = $token;
}
else {
$words[$token_value]['score'] += $token['score'];
}
unset($token_value);
}
if ($words) {
$field_name = self::getTextFieldName($name);
foreach ($words as $word) {
$score = round($word['score'] * $boost * self::SCORE_MULTIPLIER);
// Take care that the score doesn't exceed the maximum value for
// the database column (2^32-1).
$score = min((int) $score, 4294967295);
$text_inserts[$table][] = array(
'item_id' => $id,
'field_name' => $field_name,
'word' => $word['value'],
'score' => $score,
);
}
}
}
elseif (search_api_is_list_type($type)) {
$values = array();
if (is_array($value)) {
foreach ($value as $v) {
if (isset($v)) {
$values["{$v}"] = TRUE;
}
}
$values = array_keys($values);
}
elseif (isset($value)) {
$values[] = $value;
}
if ($values) {
$insert = $this->connection
->insert($table)
->fields(array(
'item_id',
$fields[$name]['column'],
));
foreach ($values as $v) {
$insert
->values(array(
'item_id' => $id,
$fields[$name]['column'] => $v,
));
}
$insert
->execute();
}
}
elseif (isset($value)) {
$inserts[$table][$fields[$name]['column']] = $value;
}
}
foreach ($inserts as $table => $data) {
$this->connection
->insert($table)
->fields(array_merge($data, array(
'item_id' => $id,
)))
->execute();
}
foreach ($text_inserts as $table => $data) {
$query = $this->connection
->insert($table)
->fields(array(
'item_id',
'field_name',
'word',
'score',
));
foreach ($data as $row) {
$query
->values($row);
}
$query
->execute();
}
} catch (Exception $e) {
$txn
->rollback();
throw $e;
}
}