You are here

protected function SearchApiDbService::createDbQuery in Search API Database Search 7

Creates a database query for a search.

Used as a helper method in search() and getAutocompleteSuggestions().

Parameters

SearchApiQueryInterface $query: The search query for which to create the database query.

array $fields: The internal field information to use.

Return value

SelectQuery A database query object which will return the appropriate results (except for the range setting) for the given search query.

Throws

SearchApiException If some illegal query setting (unknown field, etc.) was encountered.

3 calls to SearchApiDbService::createDbQuery()
SearchApiDbService::getAutocompleteSuggestions in ./service.inc
Implements SearchApiAutocompleteInterface::getAutocompleteSuggestions().
SearchApiDbService::getFacets in ./service.inc
Computes facets for a search query.
SearchApiDbService::search in ./service.inc
Executes a search on the server represented by this object.

File

./service.inc, line 1265
Contains SearchApiDbService.

Class

SearchApiDbService
Indexes and searches items using the database.

Code

protected function createDbQuery(SearchApiQueryInterface $query, array $fields) {
  $keys =& $query
    ->getKeys();
  $keys_set = (bool) $keys;
  $tokenizer_active = static::isTokenizerActive($query
    ->getIndex());
  $keys = $this
    ->prepareKeys($keys, $tokenizer_active);

  // Special case: if the outermost $keys array has "#negation" set, we can't
  // handle it like other negated subkeys. To avoid additional complexity
  // later, we just wrap $keys so it becomes a subkey.
  if (!empty($keys['#negation'])) {
    $keys = array(
      '#conjunction' => 'AND',
      $keys,
    );
  }

  // Only filter by fulltext keys if there are any real keys present.
  if ($keys && (!is_array($keys) || count($keys) > 2 || !isset($keys['#negation']) && count($keys) > 1)) {
    $fulltext_fields = $query
      ->getFields();
    if ($fulltext_fields) {
      $_fulltext_fields = $fulltext_fields;
      $fulltext_fields = array();
      foreach ($_fulltext_fields as $name) {
        if (!isset($fields[$name])) {
          throw new SearchApiException(t('Unknown field @field specified as search target.', array(
            '@field' => $name,
          )));
        }
        if (!search_api_is_text_type($fields[$name]['type'])) {
          $types = search_api_field_types();
          $type = $types[$fields[$name]['type']];
          throw new SearchApiException(t('Cannot perform fulltext search on field @field of type @type.', array(
            '@field' => $name,
            '@type' => $type,
          )));
        }
        $fulltext_fields[$name] = $fields[$name];
      }
      $db_query = $this
        ->createKeysQuery($keys, $fulltext_fields, $fields);
      if (is_array($keys) && !empty($keys['#negation'])) {
        $db_query
          ->addExpression(':score', 'score', array(
          ':score' => self::SCORE_MULTIPLIER,
        ));
        $db_query
          ->distinct();
      }
    }
    else {
      $msg = t('Search keys are given but no fulltext fields are defined.');
      watchdog('search_api_db', $msg, NULL, WATCHDOG_WARNING);
      $this->warnings[$msg] = 1;
    }
  }
  elseif ($keys_set) {
    $msg = t('No valid search keys were present in the query.');
    $this->warnings[$msg] = 1;
  }
  if (!isset($db_query)) {
    $db_query = $this->connection
      ->select($fields['search_api_language']['table'], 't');
    $db_query
      ->addField('t', 'item_id', 'item_id');
    $db_query
      ->addExpression(':score', 'score', array(
      ':score' => self::SCORE_MULTIPLIER,
    ));
    $db_query
      ->distinct();
  }
  $filter = $query
    ->getFilter();
  if ($filter
    ->getFilters()) {
    $condition = $this
      ->createFilterCondition($filter, $fields, $db_query, $query
      ->getIndex());
    if ($condition) {
      $db_query
        ->condition($condition);
    }
  }
  $db_query
    ->addTag('search_api_db_search');
  $db_query
    ->addMetaData('search_api_query', $query);
  $db_query
    ->addMetaData('search_api_db_fields', $fields);

  // Allow subclasses and other modules to alter the query.
  drupal_alter('search_api_db_query', $db_query, $query);
  $this
    ->preQuery($db_query, $query);
  return $db_query;
}