function SearchQuery::prepareAndNormalize
Same name in other branches
- 9 core/modules/search/src/SearchQuery.php \Drupal\search\SearchQuery::prepareAndNormalize()
- 8.9.x core/modules/search/src/SearchQuery.php \Drupal\search\SearchQuery::prepareAndNormalize()
- 10 core/modules/search/src/SearchQuery.php \Drupal\search\SearchQuery::prepareAndNormalize()
Prepares the query and calculates the normalization factor.
After the query is normalized the keywords are weighted to give the results a relevancy score. The query is ready for execution after this.
Error and warning conditions can apply. Call getStatus() after calling this method to retrieve them.
Return value
bool TRUE if at least one keyword matched the search index; FALSE if not.
2 calls to SearchQuery::prepareAndNormalize()
- SearchQuery::countQuery in core/
modules/ search/ src/ SearchQuery.php - Builds the default count query for SearchQuery.
- SearchQuery::preExecute in core/
modules/ search/ src/ SearchQuery.php - Generic preparation and validation for a SELECT query.
File
-
core/
modules/ search/ src/ SearchQuery.php, line 393
Class
- SearchQuery
- Search query extender and helper functions.
Namespace
Drupal\searchCode
public function prepareAndNormalize() {
$this->parseSearchExpression();
$this->executedPrepare = TRUE;
if (count($this->words) == 0) {
// Although the query could proceed, there is no point in joining
// with other tables and attempting to normalize if there are no
// keywords present.
$this->status |= SearchQuery::NO_POSITIVE_KEYWORDS;
return FALSE;
}
// Build the basic search query: match the entered keywords.
$or = $this->connection
->condition('OR');
foreach ($this->words as $word) {
$or->condition('i.word', $word);
}
$this->condition($or);
// Add keyword normalization information to the query.
$this->join('search_total', 't', '[i].[word] = [t].[word]');
$this->condition('i.type', $this->type)
->groupBy('i.type')
->groupBy('i.sid');
// If the query is simple, we should have calculated the number of
// matching words we need to find, so impose that criterion. For non-
// simple queries, this condition could lead to incorrectly deciding not
// to continue with the full query.
if ($this->simple) {
$this->having('COUNT(*) >= :matches', [
':matches' => $this->matches,
]);
}
// Clone the query object to calculate normalization.
$normalize_query = clone $this->query;
// For complex search queries, add the LIKE conditions; if the query is
// simple, we do not need them for normalization.
if (!$this->simple) {
$normalize_query->join('search_dataset', 'd', '[i].[sid] = [d].[sid] AND [i].[type] = [d].[type] AND [i].[langcode] = [d].[langcode]');
if (count($this->conditions)) {
$normalize_query->condition($this->conditions);
}
}
// Calculate normalization, which is the max of all the search scores for
// positive keywords in the query. And note that the query could have other
// fields added to it by the user of this extension.
$normalize_query->addExpression('SUM([i].[score] * [t].[count])', 'calculated_score');
$result = $normalize_query->range(0, 1)
->orderBy('calculated_score', 'DESC')
->execute()
->fetchObject();
if (isset($result->calculated_score)) {
$this->normalize = (double) $result->calculated_score;
}
if ($this->normalize) {
return TRUE;
}
// If the normalization value was zero, that indicates there were no
// matches to the supplied positive keywords.
$this->status |= SearchQuery::NO_KEYWORD_MATCHES;
return FALSE;
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.