Skip navigation
Help

do_search

6 search.module do_search($keywords, $type, $join1 = '', $where1 = '1 = 1', $arguments1 = array(), $columns2 = 'i.relevance AS score', $join2 = '', $arguments2 = array(), $sort_parameters = 'ORDER BY score DESC')

Do a query on the full-text search index for a word or words.

This function is normally only called by each module that support the indexed search (and thus, implements hook_update_index()).

Results are retrieved in two logical passes. However, the two passes are joined together into a single query. And in the case of most simple queries the second pass is not even used.

The first pass selects a set of all possible matches, which has the benefit of also providing the exact result set for simple "AND" or "OR" searches.

The second portion of the query further refines this set by verifying advanced text conditions (such negative or phrase matches)

Parameters

$keywords: A search string as entered by the user.

$type: A string identifying the calling module.

$join1: (optional) Inserted into the JOIN part of the first SQL query. For example "INNER JOIN {node} n ON n.nid = i.sid".

$where1: (optional) Inserted into the WHERE part of the first SQL query. For example "(n.status > %d)".

$arguments1: (optional) Extra SQL arguments belonging to the first query.

$columns2: (optional) Inserted into the SELECT pat of the second query. Must contain a column selected as 'score'. defaults to 'i.relevance AS score'

$join2: (optional) Inserted into the JOIN par of the second SQL query. For example "INNER JOIN {node_comment_statistics} n ON n.nid = i.sid"

$arguments2: (optional) Extra SQL arguments belonging to the second query parameter.

$sort_parameters: (optional) SQL arguments for sorting the final results. Default: 'ORDER BY score DESC'

Return value

An array of objects for the search results.

Related topics

2 calls to do_search()

File

drupal/modules/search/search.module, line 917
Enables site-wide keyword searching.

Code

function do_search($keywords, $type, $join1 = '', $where1 = '1 = 1', $arguments1 = array(), $columns2 = 'i.relevance AS score', $join2 = '', $arguments2 = array(), $sort_parameters = 'ORDER BY score DESC') {
  $query = search_parse_query($keywords);

  if ($query[2] == '') {
    form_set_error('keys', t('You must include at least one positive keyword with @count characters or more.', array('@count' => variable_get('minimum_word_size', 3))));
  }
  if ($query[6]) {
    if ($query[6] == 'or') {
      drupal_set_message(t('Search for either of the two terms with uppercase <strong>OR</strong>. For example, <strong>cats OR dogs</strong>.'));
    }
  }
  if ($query === NULL || $query[0] == '' || $query[2] == '') {
    return array();
  }

  // Build query for keyword normalization.
  $conditions = "$where1 AND ($query[2]) AND i.type = '%s'";
  $arguments1 = array_merge($arguments1, $query[3], array($type));
  $join = "INNER JOIN {search_total} t ON i.word = t.word $join1";
  if (!$query[5]) {
    $conditions .= " AND ($query[0])";
    $arguments1 = array_merge($arguments1, $query[1]);
    $join .= " INNER JOIN {search_dataset} d ON i.sid = d.sid AND i.type = d.type";
  }

  // Calculate maximum keyword relevance, to normalize it.
  $select = "SELECT SUM(i.score * t.count) AS score FROM {search_index} i $join WHERE $conditions GROUP BY i.type, i.sid HAVING COUNT(*) >= %d ORDER BY score DESC";
  $arguments = array_merge($arguments1, array($query[4]));
  $normalize = db_result(db_query_range($select, $arguments, 0, 1));
  if (!$normalize) {
    return array();
  }
  $columns2 = str_replace('i.relevance', '(' . (1.0 / $normalize) . ' * SUM(i.score * t.count))', $columns2);

  // Build query to retrieve results.
  $select = "SELECT i.type, i.sid, $columns2 FROM {search_index} i $join $join2 WHERE $conditions GROUP BY i.type, i.sid HAVING COUNT(*) >= %d";
  $count_select =  "SELECT COUNT(*) FROM ($select) n1";
  $arguments = array_merge($arguments2, $arguments1, array($query[4]));

  // Do actual search query
  $result = pager_query("$select $sort_parameters", 10, 0, $count_select, $arguments);
  $results = array();
  while ($item = db_fetch_object($result)) {
    $results[] = $item;
  }
  return $results;
}