Пример #1
0
 /**
  * Simple Search interface
  *
  * @param string|array $query   The raw query string
  * @param array $params Params  can be specified like this:
  *        'offset'            - The starting offset for result documents
  *        'limit              - The maximum number of result documents to return
  *        'sort_by'           - Sort field, can be just sort field name (and asceding order will be used by default),
  *                              or can be an array of arrays like this: array('sort_field_name' => 'asc|desc')
  *                              to define sort order and sorting fields.
  *                              If sort order not asc|desc - asceding will used by default
  *        'fields'            - Fields names which are need to be retrieved from found documents
  *        'solr_params'       - Key / value pairs for other query parameters (see Solr documentation),
  *                              use arrays for parameter keys used more than once (e.g. facet.field)
  *        'locale_code'       - Locale code, it used to define what suffix is needed for text fields,
  *                              by which will be performed search request and sorting
  *        'ignore_handler'    - Flag that allows to ignore handler (qt) and make multifield search
  *
  * @return array
  */
 protected function _search($query, $params = array())
 {
     /**
      * Hard code to prevent Solr bug:
      * Bug #17009 Creating two SolrQuery objects leads to wrong query value
      * @link http://pecl.php.net/bugs/bug.php?id=17009&edit=1
      * @link http://svn.php.net/viewvc?view=revision&revision=293379
      */
     if ((int) ('1' . str_replace('.', '', solr_get_version())) < 1099) {
         $this->_connect();
     }
     $searchConditions = $this->prepareSearchConditions($query);
     if (!$searchConditions) {
         return array();
     }
     $_params = $this->_defaultQueryParams;
     if (is_array($params) && !empty($params)) {
         $_params = array_intersect_key($params, $_params) + array_diff_key($_params, $params);
     }
     $offset = isset($_params['offset']) ? (int) $_params['offset'] : 0;
     $limit = isset($_params['limit']) ? (int) $_params['limit'] : Enterprise_Search_Model_Adapter_Solr_Abstract::DEFAULT_ROWS_LIMIT;
     /**
      * Now supported search only in fulltext field
      * By default in Solr  set <defaultSearchField> is "fulltext"
      * When language fields need to be used, then perform search in appropriate field
      */
     $languageSuffix = $this->_getLanguageSuffix($params['locale_code']);
     $solrQuery = new SolrQuery();
     $solrQuery->setStart($offset)->setRows($limit);
     $solrQuery->setQuery($searchConditions);
     if (!is_array($_params['fields'])) {
         $_params['fields'] = array($_params['fields']);
     }
     if (!is_array($_params['solr_params'])) {
         $_params['solr_params'] = array($_params['solr_params']);
     }
     /**
      * Add sort fields
      */
     if ($limit > 1) {
         $sortFields = $this->_prepareSortFields($_params['sort_by']);
         foreach ($sortFields as $sortField) {
             $sortField['sortType'] = $sortField['sortType'] == 'desc' ? SolrQuery::ORDER_DESC : SolrQuery::ORDER_ASC;
             $solrQuery->addSortField($sortField['sortField'], $sortField['sortType']);
         }
     }
     /**
      * Fields to retrieve
      */
     if ($limit && !empty($_params['fields'])) {
         foreach ($_params['fields'] as $field) {
             $solrQuery->addField($field);
         }
     }
     /**
      * Now supported search only in fulltext and name fields based on dismax requestHandler (named as magento_lng).
      * Using dismax requestHandler for each language make matches in name field
      * are much more significant than matches in fulltext field.
      */
     if ($_params['ignore_handler'] !== true) {
         $_params['solr_params']['qt'] = 'magento' . $languageSuffix;
     }
     /**
      * Facets search
      */
     $useFacetSearch = isset($params['solr_params']['facet']) && $params['solr_params']['facet'] == 'on';
     if ($useFacetSearch) {
         $_params['solr_params'] += $this->_prepareFacetConditions($params['facet']);
     }
     /**
      * Suggestions search
      */
     $useSpellcheckSearch = isset($params['solr_params']['spellcheck']) && $params['solr_params']['spellcheck'] == 'true';
     if ($useSpellcheckSearch) {
         if (isset($params['solr_params']['spellcheck.count']) && (int) $params['solr_params']['spellcheck.count'] > 0) {
             $spellcheckCount = (int) $params['solr_params']['spellcheck.count'];
         } else {
             $spellcheckCount = self::DEFAULT_SPELLCHECK_COUNT;
         }
         $_params['solr_params'] += array('spellcheck.collate' => 'true', 'spellcheck.dictionary' => 'magento_spell' . $languageSuffix, 'spellcheck.extendedResults' => 'true', 'spellcheck.count' => $spellcheckCount);
     }
     /**
      * Specific Solr params
      */
     if (!empty($_params['solr_params'])) {
         foreach ($_params['solr_params'] as $name => $value) {
             if (is_array($value)) {
                 foreach ($value as $val) {
                     $solrQuery->addParam($name, $val);
                 }
             } else {
                 $solrQuery->addParam($name, $value);
             }
         }
     }
     $filtersConditions = $this->_prepareFilters($_params['filters']);
     foreach ($filtersConditions as $condition) {
         $solrQuery->addFilterQuery($condition);
     }
     $this->_client->setServlet(SolrClient::SEARCH_SERVLET_TYPE, 'select');
     /**
      * Store filtering
      */
     if ($_params['store_id'] > 0) {
         $solrQuery->addFilterQuery('store_id:' . $_params['store_id']);
     }
     if (!Mage::helper('cataloginventory')->isShowOutOfStock()) {
         $solrQuery->addFilterQuery('in_stock:true');
     }
     try {
         $this->ping();
         $response = $this->_client->query($solrQuery);
         $data = $response->getResponse();
         if (!isset($params['solr_params']['stats']) || $params['solr_params']['stats'] != 'true') {
             if ($limit > 0) {
                 $result = array('ids' => $this->_prepareQueryResponse($data));
             }
             /**
              * Extract facet search results
              */
             if ($useFacetSearch) {
                 $result['faceted_data'] = $this->_prepareFacetsQueryResponse($data);
             }
             /**
              * Extract suggestions search results
              */
             if ($useSpellcheckSearch) {
                 $resultSuggestions = $this->_prepareSuggestionsQueryResponse($data);
                 /* Calc results count for each suggestion */
                 if (isset($params['spellcheck_result_counts']) && $params['spellcheck_result_counts'] == true && count($resultSuggestions) && $spellcheckCount > 0) {
                     /* Temporary store value for main search query */
                     $tmpLastNumFound = $this->_lastNumFound;
                     unset($params['solr_params']['spellcheck']);
                     unset($params['solr_params']['spellcheck.count']);
                     unset($params['spellcheck_result_counts']);
                     $suggestions = array();
                     foreach ($resultSuggestions as $key => $item) {
                         $this->_lastNumFound = 0;
                         $this->search($item['word'], $params);
                         if ($this->_lastNumFound) {
                             $resultSuggestions[$key]['num_results'] = $this->_lastNumFound;
                             $suggestions[] = $resultSuggestions[$key];
                             $spellcheckCount--;
                         }
                         if ($spellcheckCount <= 0) {
                             break;
                         }
                     }
                     /* Return store value for main search query */
                     $this->_lastNumFound = $tmpLastNumFound;
                 } else {
                     $suggestions = array_slice($resultSuggestions, 0, $spellcheckCount);
                 }
                 $result['suggestions_data'] = $suggestions;
             }
         } else {
             $result = $this->_prepateStatsQueryResponce($data);
         }
         return $result;
     } catch (Exception $e) {
         Mage::logException($e);
     }
 }