示例#1
0
 /**
  * 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;
 }