/** * Retrieves all options set for this search query. * * The return value is a reference to the options so they can also be altered * this way. * * @return array * An associative array of query options. * * @see \Drupal\search_api\Query\QueryInterface::getOptions() */ public function &getOptions() { if (!$this->shouldAbort()) { return $this->query->getOptions(); } $ret = NULL; return $ret; }
public function getAutocompleteSuggestions(QueryInterface $query, SearchApiAutocompleteSearch $search, $incomplete_key, $user_input) { $suggestions = array(); // Reset request handler $this->request_handler = NULL; // Turn inputs to lower case, otherwise we get case sensivity problems. $incomp = Unicode::strtolower($incomplete_key); $index = $query->getIndex(); $field_names = $this->getFieldNames($index); $complete = $query->getOriginalKeys(); // Extract keys $keys = $query->getKeys(); if (is_array($keys)) { $keys_array = array(); while ($keys) { reset($keys); if (!element_child(key($keys))) { array_shift($keys); continue; } $key = array_shift($keys); if (is_array($key)) { $keys = array_merge($keys, $key); } else { $keys_array[$key] = $key; } } $keys = $this->getSolrHelper()->flattenKeys($query->getKeys()); } else { $keys_array = preg_split('/[-\\s():{}\\[\\]\\\\"]+/', $keys, -1, PREG_SPLIT_NO_EMPTY); $keys_array = array_combine($keys_array, $keys_array); } if (!$keys) { $keys = NULL; } // Set searched fields $options = $query->getOptions(); $search_fields = $query->getFulltextFields(); $qf = array(); foreach ($search_fields as $f) { $qf[] = $field_names[$f]; } // Extract filters $fq = $this->createFilterQueries($query->getFilter(), $field_names, $index->getOption('fields', array())); $index_id = $this->getIndexId($index->id()); $fq[] = 'index_id:' . $this->getQueryHelper()->escapePhrase($index_id); if ($this->configuration['site_hash']) { $site_hash = $this->getQueryHelper()->escapePhrase(SearchApiSolrUtility::getSiteHash()); $fq[] = 'hash:' . $site_hash; } // Autocomplete magic $facet_fields = array(); foreach ($search_fields as $f) { $facet_fields[] = $field_names[$f]; } $limit = $query->getOption('limit', 10); $params = array('qf' => $qf, 'fq' => $fq, 'rows' => 0, 'facet' => 'true', 'facet.field' => $facet_fields, 'facet.prefix' => $incomp, 'facet.limit' => $limit * 5, 'facet.mincount' => 1, 'spellcheck' => !isset($this->configuration['autocorrect_spell']) || $this->configuration['autocorrect_spell'] ? 'true' : 'false', 'spellcheck.count' => 1); // Retrieve http method from server options. $http_method = !empty($this->configuration['http_method']) ? $this->configuration['http_method'] : 'AUTO'; $call_args = array('query' => &$keys, 'params' => &$params, 'http_method' => &$http_method); if ($this->request_handler) { $this->setRequestHandler($this->request_handler, $call_args); } $second_pass = !isset($this->configuration['autocorrect_suggest_words']) || $this->configuration['autocorrect_suggest_words']; for ($i = 0; $i < ($second_pass ? 2 : 1); ++$i) { try { // Send search request $this->connect(); $this->moduleHandler->alter('search_api_solr_query', $call_args, $query); $this->preQuery($call_args, $query); $response = $this->solr->search($keys, $params, $http_method); if (!empty($response->spellcheck->suggestions)) { $replace = array(); foreach ($response->spellcheck->suggestions as $word => $data) { $replace[$word] = $data->suggestion[0]; } $corrected = str_ireplace(array_keys($replace), array_values($replace), $user_input); if ($corrected != $user_input) { array_unshift($suggestions, array('prefix' => $this->t('Did you mean') . ':', 'user_input' => $corrected)); } } $matches = array(); if (isset($response->facet_counts->facet_fields)) { foreach ($response->facet_counts->facet_fields as $terms) { foreach ($terms as $term => $count) { if (isset($matches[$term])) { // If we just add the result counts, we can easily get over the // total number of results if terms appear in multiple fields. // Therefore, we just take the highest value from any field. $matches[$term] = max($matches[$term], $count); } else { $matches[$term] = $count; } } } if ($matches) { // Eliminate suggestions that are too short or already in the query. foreach ($matches as $term => $count) { if (strlen($term) < 3 || isset($keys_array[$term])) { unset($matches[$term]); } } // Don't suggest terms that are too frequent (by default in more // than 90% of results). $result_count = $response->response->numFound; $max_occurrences = $result_count * $this->searchApiSolrSettings->get('autocomplete_max_occurrences'); if (($max_occurrences >= 1 || $i > 0) && $max_occurrences < $result_count) { foreach ($matches as $match => $count) { if ($count > $max_occurrences) { unset($matches[$match]); } } } // The $count in this array is actually a score. We want the // highest ones first. arsort($matches); // Shorten the array to the right ones. $additional_matches = array_slice($matches, $limit - count($suggestions), NULL, TRUE); $matches = array_slice($matches, 0, $limit, TRUE); // Build suggestions using returned facets $incomp_length = strlen($incomp); foreach ($matches as $term => $count) { if (Unicode::strtolower(substr($term, 0, $incomp_length)) == $incomp) { $suggestions[] = array('suggestion_suffix' => substr($term, $incomp_length), 'term' => $term, 'results' => $count); } else { $suggestions[] = array('suggestion_suffix' => ' ' . $term, 'term' => $term, 'results' => $count); } } } } } catch (SearchApiException $e) { watchdog_exception('search_api_solr', $e, "%type during autocomplete Solr query: !message in %function (line %line of %file).", array(), WATCHDOG_WARNING); } if (count($suggestions) >= $limit) { break; } // Change parameters for second query. unset($params['facet.prefix']); $keys = trim($keys . ' ' . $incomplete_key); } return $suggestions; }