Ejemplo n.º 1
0
 /**
  * {@inheritdoc}
  */
 public function search(QueryInterface $query)
 {
     // Reset request handler.
     $this->request_handler = NULL;
     // Get field information.
     /** @var \Drupal\search_api\Entity\Index $index */
     $index = $query->getIndex();
     $index_id = $this->getIndexId($index->id());
     $field_names = $this->getFieldNames($index);
     $field_names_single_value = $this->getFieldNames($index, TRUE);
     // Get Solr connection.
     $this->connect();
     // Instantiate a Solarium select query.
     $solarium_query = $this->solr->createSelect();
     // Extract keys.
     $keys = $query->getKeys();
     if (is_array($keys)) {
         $keys = $this->getSolrHelper()->flattenKeys($keys);
     }
     // Set them
     $solarium_query->setQuery($keys);
     unset($keys);
     $returned_fields = array('item_id', 'score');
     if (!$this->configuration['site_hash']) {
         $returned_fields[] = 'hash';
     }
     $solarium_query->setFields($returned_fields);
     // Set searched fields.
     $options = $query->getOptions();
     $search_fields = $this->getQueryFulltextFields($query);
     // Get the index fields to be able to retrieve boosts.
     $index_fields = $index->getFields();
     $query_fields = array();
     foreach ($search_fields as $search_field) {
         /** @var \Solarium\QueryType\Update\Query\Document\Document $document */
         $document = $index_fields[$search_field];
         $boost = $document->getBoost() ? '^' . $document->getBoost() : '';
         $query_fields[] = $field_names[$search_field] . $boost;
     }
     $solarium_query->getEDisMax()->setQueryFields(implode(' ', $query_fields));
     // Handle More Like This requests
     $mlt_options = $query->getOption('search_api_mlt');
     if ($mlt_options) {
         $index_fields = $index->getFields();
         $this->getSolrHelper()->setMoreLikeThis($solarium_query, $query, $mlt_options, $index_fields, $field_names);
         // Override the search key by setting it to the solr document id
         // we want to compare it with
         // @todo. Figure out how we can set MLT earlier in the process
         // so we do not do unnecessary function calls
         $id = $this->createId($index_id, $mlt_options['id']);
         $id = static::getQueryHelper()->escapePhrase($id);
         $solarium_query->setQuery('id:' . $id);
     }
     // Set basic filters.
     $conditions_queries = $this->createFilterQueries($query->getConditionGroup(), $field_names, $index->getFields());
     foreach ($conditions_queries as $id => $conditions_query) {
         $solarium_query->createFilterQuery('filters_' . $id)->setQuery($conditions_query);
     }
     // Set the Index filter
     $solarium_query->createFilterQuery('index_id')->setQuery('index_id:' . static::getQueryHelper($solarium_query)->escapePhrase($index_id));
     // Set the site hash filter, if enabled.
     if ($this->configuration['site_hash']) {
         $site_hash = $this->getQueryHelper()->escapePhrase(SearchApiSolrUtility::getSiteHash());
         $solarium_query->createFilterQuery('site_hash')->setQuery('hash:' . $site_hash);
     }
     // Set sorts.
     $this->solrHelper->setSorts($solarium_query, $query, $field_names_single_value);
     // Set facet fields.
     $facets = $query->getOption('search_api_facets', array());
     $this->setFacets($facets, $field_names, $solarium_query);
     // Set highlighting.
     $excerpt = !empty($this->configuration['excerpt']) ? true : false;
     $highlight_data = !empty($this->configuration['highlight_data']) ? true : false;
     $this->getSolrHelper()->setHighlighting($solarium_query, $query, $excerpt, $highlight_data);
     // Handle spatial filters.
     $spatial_options = $query->getOption('search_api_location');
     if ($spatial_options) {
         $this->solrHelper->setSpatial($solarium_query, $query, $spatial_options, $field_names);
     }
     // Handle field collapsing / grouping.
     $grouping_options = $query->getOption('search_api_grouping');
     if (!empty($grouping_options['use_grouping'])) {
         $this->solrHelper->setGrouping($solarium_query, $query, $grouping_options, $index_fields, $field_names);
     }
     if (isset($options['offset'])) {
         $solarium_query->setStart($options['offset']);
     }
     $rows = isset($options['limit']) ? $options['limit'] : 1000000;
     $solarium_query->setRows($rows);
     if (!empty($options['search_api_spellcheck'])) {
         $solarium_query->getSpellcheck();
     }
     /**
      * @todo Make this more configurable so that views can choose which fields
      * it wants to fetch
      */
     if (!empty($this->configuration['retrieve_data'])) {
         $solarium_query->setFields(array('*', 'score'));
     }
     // Allow modules to alter the query
     try {
         $this->moduleHandler->alter('search_api_solr_query', $solarium_query, $query);
         $this->preQuery($solarium_query, $query);
         // Use the 'postbigrequest' plugin if no specific http method is
         // configured. The plugin needs to be loaded before the request is
         // created.
         if ($this->configuration['http_method'] == 'AUTO') {
             $this->solr->getPlugin('postbigrequest');
         }
         // Use the manual method of creating a Solarium request so we can control
         // the HTTP method.
         $request = $this->solr->createRequest($solarium_query);
         // Set the configured HTTP method.
         if ($this->configuration['http_method'] == 'POST') {
             $request->setMethod(Request::METHOD_POST);
         } elseif ($this->configuration['http_method'] == 'GET') {
             $request->setMethod(Request::METHOD_GET);
         }
         // Set HTTP Basic Authentication parameter, if login data was set.
         if (strlen($this->configuration['http_user']) && strlen($this->configuration['http_pass'])) {
             $request->setAuthentication($this->configuration['http_user'], $this->configuration['http_pass']);
         }
         // Send search request.
         $response = $this->solr->executeRequest($request);
         $resultset = $this->solr->createResult($solarium_query, $response);
         // Extract results.
         $results = $this->extractResults($query, $resultset);
         // Add warnings, if present.
         if (!empty($warnings)) {
             foreach ($warnings as $warning) {
                 $results->addWarning($warning);
             }
         }
         // Extract facets.
         if ($resultset instanceof Result) {
             if ($facets = $this->extractFacets($query, $resultset)) {
                 $results->setExtraData('search_api_facets', $facets);
             }
         }
         $this->moduleHandler->alter('search_api_solr_search_results', $results, $query, $resultset);
         $this->postQuery($results, $query, $resultset);
         return $results;
     } catch (SearchApiException $e) {
         throw new SearchApiException(t('An error occurred while trying to search with Solr: @msg.', array('@msg' => $e->getMessage())));
     }
 }