Searches in this index.
public search ( string | array | |
||
$query | string | array | |
Array with all query data inside or a Elastica\Query object |
$options | integer | array | OPTIONAL Limit or associative array of options (option=>value) |
return | with all results inside |
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'])); }
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']); }
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) { } } }
/** * Run a search query. * * @param \Elastica\Query $query * @return \Elastica\ResultSet */ public function search(\Elastica\Query $query) { return $this->_index->search($query); }