public function testQuery()
 {
     $query = new SimpleQueryString("gibson +sg +-faded", array("make", "model"));
     $results = $this->_index->search($query);
     $this->assertEquals(2, $results->getTotalHits());
     $query->setFields(array("model"));
     $results = $this->_index->search($query);
     // We should not get any hits, since the "make" field was not included in the query.
     $this->assertEquals(0, $results->getTotalHits());
 }
 public function testSuggestNoResults()
 {
     $termSuggest = new Term('suggest1', '_all');
     $termSuggest->setText('Foobar')->setSize(4);
     $result = $this->_index->search($termSuggest);
     $this->assertEquals(1, $result->countSuggests());
     // Assert that no suggestions were returned
     $suggests = $result->getSuggests();
     $this->assertEquals(0, sizeof($suggests['suggest1'][0]['options']));
 }
Example #3
0
 public function testQuery()
 {
     $query = new Query();
     $match = new Match();
     $match->setField('make', 'ford');
     $query->setQuery($match);
     $filter = new Term();
     $filter->setTerm('color', 'green');
     $query->setPostFilter($filter);
     $results = $this->_index->search($query);
     $this->assertEquals(1, $results->getTotalHits());
 }
 public function testPhraseSuggest()
 {
     $suggest = new Suggest();
     $phraseSuggest = new Phrase('suggest1', 'text');
     $phraseSuggest->setText("elasticsearch is bansai coor");
     $phraseSuggest->setAnalyzer("simple")->setHighlight("<suggest>", "</suggest>")->setStupidBackoffSmoothing(0.4);
     $phraseSuggest->addCandidateGenerator(new DirectGenerator("text"));
     $suggest->addSuggestion($phraseSuggest);
     $result = $this->_index->search($suggest);
     $suggests = $result->getSuggests();
     // 3 suggestions should be returned: One in which both misspellings are corrected, and two in which only one misspelling is corrected.
     $this->assertEquals(3, sizeof($suggests['suggest1'][0]['options']));
     $this->assertEquals("elasticsearch is <suggest>bonsai cool</suggest>", $suggests['suggest1'][0]['options'][0]['highlighted']);
     $this->assertEquals("elasticsearch is bonsai cool", $suggests['suggest1'][0]['options'][0]['text']);
 }
Example #5
0
 public function testQuery()
 {
     $client = $this->_getClient();
     $index = new Index($client, 'test');
     $index->create(array(), true);
     $type = new Type($index, 'multi_match');
     $doc = new Document(1, array('id' => 1, 'name' => 'Rodolfo', 'last_name' => 'Moraes'));
     $type->addDocument($doc);
     // Refresh index
     $index->refresh();
     $multiMatch = new MultiMatch();
     $query = new Query();
     $multiMatch->setQuery('Rodolfo');
     $multiMatch->setFields(array('name', 'last_name'));
     $query->setQuery($multiMatch);
     $resultSet = $index->search($query);
     $this->assertEquals(1, $resultSet->count());
     $multiMatch->setQuery('Moraes');
     $multiMatch->setFields(array('name', 'last_name'));
     $query->setQuery($multiMatch);
     $resultSet = $index->search($query);
     $this->assertEquals(1, $resultSet->count());
 }
 /**
  * Run the search against a sanitized query string via ElasticSearch.
  *
  * @param string $string
  * @param array $scriptProperties The scriptProperties array from the SimpleSearch snippet
  * @return array
  */
 public function search($string, array $scriptProperties = array())
 {
     $fields = $this->modx->getOption('sisea.elastic.search_fields', null, 'pagetitle^20,introtext^10,alias^5,content^1');
     $fields = explode(',', $fields);
     $fields = array_map('trim', $fields);
     $fields = array_keys(array_flip($fields));
     $fields = array_filter($fields);
     if (empty($fields)) {
         return false;
     }
     /** @var \Elastica\Query\MultiMatch $query */
     $query = new \Elastica\Query\MultiMatch();
     $query->setFields($fields);
     $query->setQuery($string);
     $customFilterScore = new \Elastica\Query\CustomFiltersScore();
     $customFilterScore->setQuery($query);
     $searchBoosts = $this->modx->getOption('sisea.elastic.search_boost', null, '');
     $searchBoosts = explode('|', $searchBoosts);
     $searchBoosts = array_map('trim', $searchBoosts);
     $searchBoosts = array_keys(array_flip($searchBoosts));
     $searchBoosts = array_filter($searchBoosts);
     $boosts = array();
     foreach ($searchBoosts as $boost) {
         $arr = array('field' => '', 'value' => '', 'boost' => 1.0);
         $field = explode('=', $boost);
         $field = array_map('trim', $field);
         $field = array_keys(array_flip($field));
         $field = array_filter($field);
         if (count($field) != 2) {
             continue;
         }
         $value = explode('^', $field[1]);
         $value = array_map('trim', $value);
         $value = array_keys(array_flip($value));
         $value = array_filter($value);
         if (count($value) != 2) {
             continue;
         }
         $arr['field'] = $field[0];
         $arr['value'] = $value[0];
         $arr['boost'] = $value[1];
         $boosts[] = $arr;
     }
     if (empty($boosts)) {
         $customFilterScore->addFilter(new \Elastica\Filter\Term(array('type' => 'document')), 1);
     } else {
         foreach ($boosts as $boost) {
             $customFilterScore->addFilter(new \Elastica\Filter\Term(array($boost['field'] => $boost['value'])), $boost['boost']);
         }
     }
     /** @var \Elastica\Query $elasticaQuery */
     $elasticaQuery = new \Elastica\Query();
     $elasticaQuery->setQuery($customFilterScore);
     /* set limit */
     $perPage = $this->modx->getOption('perPage', $scriptProperties, 10);
     if (!empty($perPage)) {
         $offset = $this->modx->getOption('start', $scriptProperties, 0);
         $offsetIndex = $this->modx->getOption('offsetIndex', $scriptProperties, 'sisea_offset');
         if (isset($_REQUEST[$offsetIndex])) {
             $offset = (int) $_REQUEST[$offsetIndex];
         }
         $elasticaQuery->setFrom($offset);
         $elasticaQuery->setSize($perPage);
     }
     $elasticaFilterAnd = new \Elastica\Filter\BoolAnd();
     /* handle hidemenu option */
     $hideMenu = $this->modx->getOption('hideMenu', $scriptProperties, 2);
     if ($hideMenu != 2) {
         $elasticaFilterHideMenu = new \Elastica\Filter\Term();
         $elasticaFilterHideMenu->setTerm('hidemenu', $hideMenu ? 1 : 0);
         $elasticaFilterAnd->addFilter($elasticaFilterHideMenu);
     }
     /* handle contexts */
     $contexts = $this->modx->getOption('contexts', $scriptProperties, '');
     $contexts = !empty($contexts) ? $contexts : $this->modx->context->get('key');
     $contexts = explode(',', $contexts);
     $elasticaFilterContext = new \Elastica\Filter\Terms();
     $elasticaFilterContext->setTerms('context_key', $contexts);
     $elasticaFilterAnd->addFilter($elasticaFilterContext);
     /* handle restrict search to these IDs */
     $ids = $this->modx->getOption('ids', $scriptProperties, '');
     if (!empty($ids)) {
         $idType = $this->modx->getOption('idType', $this->config, 'parents');
         $depth = $this->modx->getOption('depth', $this->config, 10);
         $ids = $this->processIds($ids, $idType, $depth);
         $elasticaFilterId = new \Elastica\Filter\Term();
         $elasticaFilterId->setTerm('id', $ids);
         $elasticaFilterAnd->addFilter($elasticaFilterId);
     }
     /* handle exclude IDs from search */
     $exclude = $this->modx->getOption('exclude', $scriptProperties, '');
     if (!empty($exclude)) {
         $exclude = $this->cleanIds($exclude);
         $exclude = explode(',', $exclude);
         $elasticaFilterExcludeId = new \Elastica\Filter\Term();
         $elasticaFilterExcludeId->setTerm('id', $exclude);
         $elasticaFilterNotId = new \Elastica\Filter\BoolNot($elasticaFilterExcludeId);
         $elasticaFilterAnd->addFilter($elasticaFilterNotId);
     }
     /* basic always-on conditions */
     $elasticaFilterPublished = new \Elastica\Filter\Term();
     $elasticaFilterPublished->setTerm('published', 1);
     $elasticaFilterAnd->addFilter($elasticaFilterPublished);
     $elasticaFilterSearchable = new \Elastica\Filter\Term();
     $elasticaFilterSearchable->setTerm('searchable', 1);
     $elasticaFilterAnd->addFilter($elasticaFilterSearchable);
     $elasticaFilterDeleted = new \Elastica\Filter\Term();
     $elasticaFilterDeleted->setTerm('deleted', 0);
     $elasticaFilterAnd->addFilter($elasticaFilterDeleted);
     $elasticaQuery->setFilter($elasticaFilterAnd);
     /* sorting */
     if (!empty($scriptProperties['sortBy'])) {
         $sortDir = $this->modx->getOption('sortDir', $scriptProperties, 'desc');
         $sortDirs = explode(',', $sortDir);
         $sortBys = explode(',', $scriptProperties['sortBy']);
         $dir = 'desc';
         $sortArray = array();
         for ($i = 0; $i < count($sortBys); $i++) {
             if (isset($sortDirs[$i])) {
                 $dir = $sortDirs[$i];
             }
             $sortArray[] = array($sortBys[$i] => $dir);
         }
         $elasticaQuery->setSort($sortArray);
     }
     /* prepare response array */
     $response = array('total' => 0, 'start' => !empty($offset) ? $offset : 0, 'limit' => $perPage, 'status' => 0, 'query_time' => 0, 'results' => array());
     $elasticaResultSet = $this->index->search($elasticaQuery);
     $elasticaResults = $elasticaResultSet->getResults();
     $totalResults = $elasticaResultSet->getTotalHits();
     if ($totalResults > 0) {
         $response['total'] = $totalResults;
         $response['query_time'] = $elasticaResultSet->getTotalTime();
         $response['status'] = 1;
         $response['results'] = array();
         foreach ($elasticaResults as $doc) {
             $d = $doc->getData();
             /** @var modResource $resource */
             $resource = $this->modx->newObject($d['class_key']);
             if ($resource->checkPolicy('list')) {
                 $response['results'][] = $d;
             }
         }
     }
     return $response;
 }
 /**
  * Iterate over a scroll.
  * @param \Elastica\Index $index
  * @param string $scrollId the initial $scrollId
  * @param string $scrollTime the scroll timeout
  * @param callable $consumer function that receives the results
  * @param int $limit the max number of results to fetch (0: no limit)
  * @param int $retryAttempts the number of times we retry
  * @param callable $retryErrorCallback function called before each retries
  */
 public static function iterateOverScroll(\Elastica\Index $index, $scrollId, $scrollTime, $consumer, $limit = 0, $retryAttemps = 0, $retryErrorCallback = null)
 {
     $clearScroll = true;
     $fetched = 0;
     while (true) {
         $result = static::withRetry($retryAttemps, function () use($index, $scrollId, $scrollTime) {
             return $index->search(array(), array('scroll_id' => $scrollId, 'scroll' => $scrollTime));
         }, $retryErrorCallback);
         $scrollId = $result->getResponse()->getScrollId();
         if (!$result->count()) {
             // No need to clear scroll on the last call
             $clearScroll = false;
             break;
         }
         $fetched += $result->count();
         $results = $result->getResults();
         if ($limit > 0 && $fetched > $limit) {
             $results = array_slice($results, 0, sizeof($results) - ($fetched - $limit));
         }
         $consumer($results);
         if ($limit > 0 && $fetched >= $limit) {
             break;
         }
     }
     // @todo: catch errors and clear the scroll, it'd be easy with a finally block ...
     if ($clearScroll) {
         try {
             $index->getClient()->request("_search/scroll/" . $scrollId, \Elastica\Request::DELETE);
         } catch (Exception $e) {
         }
     }
 }
Example #8
0
 /**
  * Run a search query.
  *
  * @param \Elastica\Query $query
  * @return \Elastica\ResultSet
  */
 public function search(\Elastica\Query $query)
 {
     return $this->_index->search($query);
 }