/**
  * Prepares the {@link SearchQuery}. Handles taking request arguments and
  * generating the filters and excludes to manipulate the search query.
  *
  * @return SearchQuery
  */
 protected function prepareQuery()
 {
     $params = $this->getSearchParams();
     $query = new SearchQuery();
     // Filters
     $query->search($params['q']);
     // Permission checks. CanView* checks are really basic, don't check for
     // inheritance or enforce visibility for admins or other logged-in
     // members (based on their many-many relationships).
     $query->exclude('SiteTree_ShowInSearch', false);
     $query->exclude('SiteTree_CanViewType', 'OnlyTheseUsers');
     $query->exclude('SiteTree_CanViewType', 'LoggedInUsers');
     // $query->filter('..', true)
     return $query;
 }
 /**
  * Performs the search against the snippets in the system
  *
  * @param {string} $keywords Keywords to search for
  * @param {int} $languageID Language to filter to
  * @param {int} $folderID Folder to filter to
  * @return {DataList} Data list pointing to the snippets in the results
  */
 public function doSnippetSearch($keywords, $languageID = false, $folderID = false)
 {
     $searchIndex = singleton('CodeBankSolrIndex');
     $searchQuery = new SearchQuery();
     $searchQuery->classes = array(array('class' => 'Snippet', 'includeSubclasses' => true));
     //Add language filtering
     if ($languageID !== false && $languageID > 0) {
         $searchQuery->filter('Snippet_LanguageID', $languageID);
     }
     //Add language filtering
     if ($folderID !== false && $folderID > 0) {
         $searchQuery->filter('Snippet_FolderID', $folderID);
     }
     //Configure search
     $searchQuery->search($keywords, null, array('Snippet_Title' => 2, 'Snippet_Description' => 1));
     return $searchIndex->search($searchQuery, null, null)->Matches->getList();
 }
 /**
  * @param string $keywords
  * @param array  $filters
  * @return array
  */
 public function suggestWithResults($keywords, array $filters = array())
 {
     $limit = (int) ShopSearch::config()->sayt_limit;
     // process the keywords a bit
     $terms = preg_split('/\\s+/', trim(strtolower($keywords)));
     $lastTerm = count($terms) > 0 ? array_pop($terms) : '';
     $prefix = count($terms) > 0 ? implode(' ', $terms) . ' ' : '';
     //$terms[]    = $lastTerm;
     $terms[] = $lastTerm . '*';
     // this allows for partial words to still match
     // convert that to something solr adapater can handle
     $query = new SearchQuery();
     $query->search('+' . implode(' +', $terms));
     $params = array('sort' => 'score desc', 'facet' => 'true', 'facet.field' => '_autocomplete', 'facet.limit' => ShopSearch::config()->suggest_limit, 'facet.prefix' => $lastTerm);
     //		$facetSpec = array(
     //			'_autocomplete' => array(
     //				'Type'      => ShopSearch::FACET_TYPE_LINK,
     //				'Label'     => 'Suggestions',
     //				'Source'    => '_autocomplete',
     //			),
     //		);
     //
     //		Debug::dump($query);
     //
     //		$search     = $this->search($query, 0, $limit, $params, $facetSpec);
     //		Debug::dump($search);
     //		$prodList   = $search->Matches;
     //
     //		$suggestsion = array();
     ////		if ($)
     $service = $this->getService();
     SearchVariant::with(count($query->classes) == 1 ? $query->classes[0]['class'] : null)->call('alterQuery', $query, $this);
     $q = $terms;
     $fq = array();
     // Build the search itself
     //		foreach ($query->search as $search) {
     //			$text = $search['text'];
     //			preg_match_all('/"[^"]*"|\S+/', $text, $parts);
     //
     //			$fuzzy = $search['fuzzy'] ? '~' : '';
     //
     //			foreach ($parts[0] as $part) {
     //				$fields = (isset($search['fields'])) ? $search['fields'] : array();
     //				if(isset($search['boost'])) $fields = array_merge($fields, array_keys($search['boost']));
     //				if ($fields) {
     //					$searchq = array();
     //					foreach ($fields as $field) {
     //						$boost = (isset($search['boost'][$field])) ? '^' . $search['boost'][$field] : '';
     //						$searchq[] = "{$field}:".$part.$fuzzy.$boost;
     //					}
     //					$q[] = '+('.implode(' OR ', $searchq).')';
     //				}
     //				else {
     //					$q[] = '+'.$part.$fuzzy;
     //				}
     //			}
     //		}
     // Filter by class if requested
     $classq = array();
     foreach ($query->classes as $class) {
         if (!empty($class['includeSubclasses'])) {
             $classq[] = 'ClassHierarchy:' . $class['class'];
         } else {
             $classq[] = 'ClassName:' . $class['class'];
         }
     }
     if ($classq) {
         $fq[] = '+(' . implode(' ', $classq) . ')';
     }
     // Filter by filters
     foreach ($query->require as $field => $values) {
         $requireq = array();
         foreach ($values as $value) {
             if ($value === SearchQuery::$missing) {
                 $requireq[] = "(*:* -{$field}:[* TO *])";
             } elseif ($value === SearchQuery::$present) {
                 $requireq[] = "{$field}:[* TO *]";
             } elseif ($value instanceof SearchQuery_Range) {
                 $start = $value->start;
                 if ($start === null) {
                     $start = '*';
                 }
                 $end = $value->end;
                 if ($end === null) {
                     $end = '*';
                 }
                 $requireq[] = "{$field}:[{$start} TO {$end}]";
             } else {
                 $requireq[] = $field . ':"' . $value . '"';
             }
         }
         $fq[] = '+(' . implode(' ', $requireq) . ')';
     }
     foreach ($query->exclude as $field => $values) {
         $excludeq = array();
         $missing = false;
         foreach ($values as $value) {
             if ($value === SearchQuery::$missing) {
                 $missing = true;
             } elseif ($value === SearchQuery::$present) {
                 $excludeq[] = "{$field}:[* TO *]";
             } elseif ($value instanceof SearchQuery_Range) {
                 $start = $value->start;
                 if ($start === null) {
                     $start = '*';
                 }
                 $end = $value->end;
                 if ($end === null) {
                     $end = '*';
                 }
                 $excludeq[] = "{$field}:[{$start} TO {$end}]";
             } else {
                 $excludeq[] = $field . ':"' . $value . '"';
             }
         }
         $fq[] = ($missing ? "+{$field}:[* TO *] " : '') . '-(' . implode(' ', $excludeq) . ')';
     }
     //		if(!headers_sent()) {
     //			if ($q) header('X-Query: '.implode(' ', $q));
     //			if ($fq) header('X-Filters: "'.implode('", "', $fq).'"');
     //		}
     $params = array_merge($params, array('fq' => implode(' ', $fq)));
     $res = $service->search(implode(' ', $q), 0, $limit, $params, Apache_Solr_Service::METHOD_POST);
     $results = new ArrayList();
     if ($res->getHttpStatus() >= 200 && $res->getHttpStatus() < 300) {
         foreach ($res->response->docs as $doc) {
             $result = DataObject::get_by_id($doc->ClassName, $doc->ID);
             if ($result) {
                 $results->push($result);
             }
         }
         $numFound = $res->response->numFound;
     } else {
         $numFound = 0;
     }
     $ret = array();
     $ret['products'] = new PaginatedList($results);
     $ret['products']->setLimitItems(false);
     $ret['products']->setTotalItems($numFound);
     $ret['products']->setPageStart(0);
     $ret['products']->setPageLength($limit);
     // Facets (this is how we're doing suggestions for now...
     $ret['suggestions'] = array();
     if (isset($res->facet_counts->facet_fields->_autocomplete)) {
         foreach ($res->facet_counts->facet_fields->_autocomplete as $term => $count) {
             $ret['suggestions'][] = $prefix . $term;
         }
     }
     // Suggestions (requires custom setup, assumes spellcheck.collate=true)
     //		if(isset($res->spellcheck->suggestions->collation)) {
     //			$ret['Suggestion'] = $res->spellcheck->suggestions->collation;
     //		}
     return $ret;
 }
 function testHighlightQueryOnBoost()
 {
     $serviceMock = $this->getServiceMock();
     Phockito::when($serviceMock)->search(anything(), anything(), anything(), anything(), anything())->return($this->getFakeRawSolrResponse());
     $index = new SolrIndexTest_FakeIndex();
     $index->setService($serviceMock);
     // Search without highlighting
     $query = new SearchQuery();
     $query->search('term', null, array('Field1' => 1.5, 'HasOneObject_Field1' => 3));
     $index->search($query);
     Phockito::verify($serviceMock)->search('+(Field1:term^1.5 OR HasOneObject_Field1:term^3)', anything(), anything(), not(hasKeyInArray('hl.q')), anything());
     // Search with highlighting
     $query = new SearchQuery();
     $query->search('term', null, array('Field1' => 1.5, 'HasOneObject_Field1' => 3));
     $index->search($query, -1, -1, array('hl' => true));
     Phockito::verify($serviceMock)->search('+(Field1:term^1.5 OR HasOneObject_Field1:term^3)', anything(), anything(), hasKeyInArray('hl.q'), anything());
 }
예제 #5
0
 /**
  * Builds a search query from a give search term.
  * @return SearchQuery
  */
 protected function getSearchQuery($keywords)
 {
     $categoryIDs = array();
     $categoryFilterID = $this->request->requestVar(self::$search_category_key);
     $categories = $this->Categories();
     if ($categories->count() == 0) {
         $categories = FAQ::getRootCategory()->Children();
     }
     $filterCategory = $categories->filter('ID', $categoryFilterID)->first();
     $categoryIDs = array();
     if ($filterCategory && $filterCategory->exists()) {
         $categoryIDs = $this->getSelectedIDs(array($filterCategory));
     } else {
         $categoryIDs = $this->Categories()->column('ID');
     }
     $query = new SearchQuery();
     $query->classes = self::$classes_to_search;
     if (count($categoryIDs) > 0) {
         $query->filter('FAQ_Category_ID', array_filter($categoryIDs, 'intval'));
     }
     $query->search($keywords);
     // Artificially lower the amount of results to prevent too high resource usage.
     // on subsequent canView check loop.
     $query->limit(100);
     return $query;
 }