/** * {@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()))); } }