public function testResponse() { $client = new Elastica_Client(); $index = $client->getIndex('test'); $index->create(array(), true); $type = $index->getType('helloworld'); $mapping = new Elastica_Type_Mapping($type, array('name' => array('type' => 'string', 'store' => 'no'), 'dtmPosted' => array('type' => 'date', 'store' => 'no', 'format' => 'yyyy-MM-dd HH:mm:ss'))); $type->setMapping($mapping); $doc = new Elastica_Document(1, array('name' => 'nicolas ruflin', 'dtmPosted' => "2011-06-23 21:53:00")); $type->addDocument($doc); $doc = new Elastica_Document(2, array('name' => 'raul martinez jr', 'dtmPosted' => "2011-06-23 09:53:00")); $type->addDocument($doc); $doc = new Elastica_Document(3, array('name' => 'rachelle clemente', 'dtmPosted' => "2011-07-08 08:53:00")); $type->addDocument($doc); $doc = new Elastica_Document(4, array('name' => 'elastica search', 'dtmPosted' => "2011-07-08 01:53:00")); $type->addDocument($doc); $query = new Elastica_Query(); $query->setQuery(new Elastica_Query_MatchAll()); $index->refresh(); $resultSet = $type->search($query); $engineTime = $resultSet->getResponse()->getEngineTime(); $shardsStats = $resultSet->getResponse()->getShardsStatistics(); $this->assertTrue($engineTime != ''); $this->assertTrue(is_array($shardsStats)); $this->assertArrayHasKey('total', $shardsStats); $this->assertArrayHasKey('successful', $shardsStats); }
public function testGeoPoint() { $client = new Elastica_Client(); $index = $client->getIndex('test'); $index->create(array(), true); $type = $index->getType('test'); // Set mapping $type->setMapping(array('point' => array('type' => 'geo_point'))); // Add doc 1 $doc1 = new Elastica_Document(1, array('name' => 'ruflin')); $doc1->addGeoPoint('point', 17, 19); $type->addDocument($doc1); // Add doc 2 $doc2 = new Elastica_Document(2, array('name' => 'ruflin')); $doc2->addGeoPoint('point', 30, 40); $type->addDocument($doc2); $index->optimize(); $index->refresh(); // Only one point should be in radius $query = new Elastica_Query(); $geoFilter = new Elastica_Filter_GeoDistance('point', array('lat' => 30, 'lon' => 40), '1km'); $query = new Elastica_Query(new Elastica_Query_MatchAll()); $query->setFilter($geoFilter); $this->assertEquals(1, $type->search($query)->count()); // Both points should be inside $query = new Elastica_Query(); $geoFilter = new Elastica_Filter_GeoDistance('point', array('lat' => 30, 'lon' => 40), '40000km'); $query = new Elastica_Query(new Elastica_Query_MatchAll()); $query->setFilter($geoFilter); $index->refresh(); $this->assertEquals(2, $type->search($query)->count()); }
public function testGeoPoint() { $client = new Elastica_Client(); $index = $client->getIndex('test'); $index->create(array(), true); $type = $index->getType('test'); // Set mapping $type->setMapping(array('point' => array('type' => 'geo_point'))); // Add doc 1 $doc1 = new Elastica_Document(1, array('name' => 'ruflin')); $doc1->addGeoPoint('point', 17, 19); $type->addDocument($doc1); // Add doc 2 $doc2 = new Elastica_Document(2, array('name' => 'ruflin')); $doc2->addGeoPoint('point', 30, 40); $type->addDocument($doc2); $index->refresh(); // Only one point should be in polygon $query = new Elastica_Query(); $points = array(array(16, 16), array(16, 20), array(20, 20), array(20, 16), array(16, 16)); $geoFilter = new Elastica_Filter_GeoPolygon('point', compact('points')); $query = new Elastica_Query(new Elastica_Query_MatchAll()); $query->setFilter($geoFilter); $this->assertEquals(1, $type->search($query)->count()); // Both points should be inside $query = new Elastica_Query(); $points = array(array(16, 16), array(16, 40), array(40, 40), array(40, 16), array(16, 16)); $geoFilter = new Elastica_Filter_GeoPolygon('point', compact('points')); $query = new Elastica_Query(new Elastica_Query_MatchAll()); $query->setFilter($geoFilter); $this->assertEquals(2, $type->search($query)->count()); }
public function testFilter() { $client = new Elastica_Client(); $index = $client->getIndex('test'); $index->create(array(), true); $type = $index->getType('helloworld'); $type->addDocument(new Elastica_Document(1, array('color' => 'red'))); $type->addDocument(new Elastica_Document(2, array('color' => 'green'))); $type->addDocument(new Elastica_Document(3, array('color' => 'blue'))); $index->refresh(); $termQuery = new Elastica_Query_Term(array('color' => 'red')); $facet = new Elastica_Facet_Query('test'); $facet->setQuery($termQuery); $query = new Elastica_Query(); $query->addFacet($facet); $resultSet = $type->search($query); $facets = $resultSet->getFacets(); $this->assertEquals(1, $facets['test']['count']); }
public function testStatisticalWithSetFields() { $client = new Elastica_Client(); $index = $client->getIndex('test'); $index->create(array(), true); $type = $index->getType('helloworld'); $doc = new Elastica_Document(1, array('price' => 10, 'price2' => 20)); $type->addDocument($doc); $doc = new Elastica_Document(2, array('price' => 35, 'price2' => 70)); $type->addDocument($doc); $doc = new Elastica_Document(2, array('price' => 45, 'price2' => 90)); $type->addDocument($doc); $facet = new Elastica_Facet_Statistical('stats'); $facet->setFields(array('price','price2')); $query = new Elastica_Query(); $query->addFacet($facet); $query->setQuery(new Elastica_Query_MatchAll()); $index->refresh(); $response = $type->search($query); $facets = $response->getFacets(); $this->assertEquals(165, $facets['stats']['total']); $this->assertEquals(10, $facets['stats']['min']); $this->assertEquals(90, $facets['stats']['max']); }
public function testSearch() { $client = new Elastica_Client(); $index = new Elastica_Index($client, 'test'); $index->create(array(), true); $index->getSettings()->setNumberOfReplicas(0); //$index->getSettings()->setNumberOfShards(1); $type = new Elastica_Type($index, 'helloworldmlt'); $mapping = new Elastica_Type_Mapping($type, array('email' => array('store' => 'yes', 'type' => 'string', 'index' => 'analyzed'), 'content' => array('store' => 'yes', 'type' => 'string', 'index' => 'analyzed'))); $mapping->setSource(array('enabled' => false)); $type->setMapping($mapping); $doc = new Elastica_Document(1000, array('email' => '*****@*****.**', 'content' => 'This is a sample post. Hello World Fuzzy Like This!')); $type->addDocument($doc); $doc = new Elastica_Document(1001, array('email' => '*****@*****.**', 'content' => 'This is a fake nospam email address for gmail')); $type->addDocument($doc); // Refresh index $index->refresh(); $mltQuery = new Elastica_Query_MoreLikeThis(); $mltQuery->setLikeText('fake gmail sample'); $mltQuery->setFields(array('email', 'content')); $mltQuery->setMaxQueryTerms(1); $mltQuery->setMinDocFrequency(1); $mltQuery->setMinTermFrequency(1); $query = new Elastica_Query(); $query->setFields(array('email', 'content')); $query->setQuery($mltQuery); $resultSet = $type->search($query); $resultSet->getResponse()->getData(); $this->assertEquals(2, $resultSet->count()); }
public function testQuery() { $client = new Elastica_Client(); $index = $client->getIndex('test'); $index->create(array(), true); $type = $index->getType('helloworld'); $doc = new Elastica_Document(1, array('name' => 'nicolas ruflin')); $type->addDocument($doc); $doc = new Elastica_Document(2, array('name' => 'ruflin test')); $type->addDocument($doc); $doc = new Elastica_Document(2, array('name' => 'nicolas helloworld')); $type->addDocument($doc); $facet = new Elastica_Facet_Terms('test'); $facet->setField('name'); $query = new Elastica_Query(); $query->addFacet($facet); $query->setQuery(new Elastica_Query_MatchAll()); $index->refresh(); $response = $type->search($query); $facets = $response->getFacets(); $this->assertEquals(3, count($facets['test']['terms'])); }
public function testTest() { $client = new Elastica_Client(); $index = $client->getIndex('test'); $index->create(array(), true); $type = $index->getType('helloworld'); $mapping = new Elastica_Type_Mapping($type, array('name' => array('type' => 'string', 'store' => 'no'), 'dtmPosted' => array('type' => 'date', 'store' => 'no', 'format' => 'yyyy-MM-dd HH:mm:ss'))); $type->setMapping($mapping); $doc = new Elastica_Document(1, array('name' => 'nicolas ruflin', 'dtmPosted' => "2011-06-23 21:53:00")); $type->addDocument($doc); $doc = new Elastica_Document(2, array('name' => 'raul martinez jr', 'dtmPosted' => "2011-06-23 09:53:00")); $type->addDocument($doc); $doc = new Elastica_Document(3, array('name' => 'rachelle clemente', 'dtmPosted' => "2011-07-08 08:53:00")); $type->addDocument($doc); $doc = new Elastica_Document(4, array('name' => 'elastica search', 'dtmPosted' => "2011-07-08 01:53:00")); $type->addDocument($doc); $facet = new Elastica_Facet_DateHistogram('dateHist1'); $facet->setInterval("day"); $facet->setField("dtmPosted"); $query = new Elastica_Query(); $query->addFacet($facet); $query->setQuery(new Elastica_Query_MatchAll()); $index->refresh(); $response = $type->search($query); $facets = $response->getFacets(); $this->assertEquals(4, $response->getTotalHits()); $this->assertEquals(2, count($facets['dateHist1']['entries'])); }
public function testQuery() { $type = $this->index->getType('test'); $doc = new Elastica_Document(1, array('firstname' => 'guschti', 'lastname' => 'ruflin')); $type->addDocument($doc); $this->index->refresh(); $query = new Elastica_Query(); $script = new Elastica_Script('1 + 2'); $scriptFields = new Elastica_ScriptFields(array('test' => $script)); $query->setScriptFields($scriptFields); $resultSet = $type->search($query); $first = $resultSet->current()->getData(); // 1 + 2 $this->assertEquals(3, $first['test']); }
public function testMappingStoreFields() { $client = new Elastica_Client(); $index = $client->getIndex('test'); $index->create(array(), true); $type = $index->getType('test'); $mapping = new Elastica_Type_Mapping($type, array('firstname' => array('type' => 'string', 'store' => 'yes'), 'lastname' => array('type' => 'string'))); $mapping->disableSource(); $type->setMapping($mapping); $firstname = 'Nicolas'; $doc = new Elastica_Document(1, array('firstname' => $firstname, 'lastname' => 'Ruflin')); $type->addDocument($doc); $index->refresh(); $queryString = new Elastica_Query_QueryString('ruflin'); $query = Elastica_Query::create($queryString); $query->setFields(array('*')); $resultSet = $type->search($query); $result = $resultSet->current(); $fields = $result->getFields(); $this->assertEquals($firstname, $fields['firstname']); $this->assertArrayNotHasKey('lastname', $fields); $this->assertEquals(1, count($fields)); $index->flush(); $document = $type->getDocument(1); $this->assertEmpty($document->getData()); }
/** * Transforms a string or an array to a query object * * If query is empty, * * @param mixed $query * @return Elastica_Query **/ public static function create($query) { switch (true) { case $query instanceof Elastica_Query: return $query; case $query instanceof Elastica_Query_Abstract: return new self($query); case $query instanceof Elastica_Filter_Abstract: $newQuery = new Elastica_Query(); $newQuery->setFilter($query); return $newQuery; case empty($query): return new self(new Elastica_Query_MatchAll()); case is_string($query): return new self(new Elastica_Query_QueryString($query)); } // TODO: Implement queries without throw new Elastica_Exception_NotImplemented(); }
public function testHightlightSearch() { $client = new Elastica_Client(); $index = $client->getIndex('test'); $index->create(array(), true); $type = $index->getType('helloworld'); $phrase = 'My name is ruflin'; $doc = new Elastica_Document(1, array('id' => 1, 'phrase' => $phrase, 'username' => 'hanswurst', 'test' => array('2', '3', '5'))); $type->addDocument($doc); $doc = new Elastica_Document(2, array('id' => 2, 'phrase' => $phrase, 'username' => 'peter', 'test' => array('2', '3', '5'))); $type->addDocument($doc); $queryString = new Elastica_Query_QueryString('rufl*'); $query = new Elastica_Query($queryString); $query->setHighlight(array('pre_tags' => array('<em class="highlight">'), 'post_tags' => array('</em>'), 'fields' => array('phrase' => array('fragment_size' => 200, 'number_of_fragments' => 1)))); $index->refresh(); $resultSet = $type->search($query); foreach ($resultSet as $result) { $highlight = $result->getHighlights(); $this->assertEquals(array('phrase' => array(0 => 'My name is <em class="highlight">ruflin</em>')), $highlight); } $this->assertEquals(2, $resultSet->count()); }
public function testQuery() { $client = new Elastica_Client(); $index = new Elastica_Index($client, 'test'); $index->create(array(), true); $type = new Elastica_Type($index, 'multi_match'); $doc = new Elastica_Document(1, array('id' => 1, 'name' => 'Rodolfo', 'last_name' => 'Moraes')); $type->addDocument($doc); // Refresh index $index->refresh(); $multiMatch = new Elastica_Query_MultiMatch(); $query = new Elastica_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()); }
public function testQuery() { $client = new Elastica_Client(); $index = $client->getIndex('test'); $index->create(array(), true); $type = $index->getType('helloworld'); $doc = new Elastica_Document(1, array('name' => 'tom', 'paid' => 7)); $type->addDocument($doc); $doc = new Elastica_Document(2, array('name' => 'tom', 'paid' => 2)); $type->addDocument($doc); $doc = new Elastica_Document(3, array('name' => 'tom', 'paid' => 5)); $type->addDocument($doc); $doc = new Elastica_Document(4, array('name' => 'mike', 'paid' => 13)); $type->addDocument($doc); $doc = new Elastica_Document(5, array('name' => 'mike', 'paid' => 1)); $type->addDocument($doc); $doc = new Elastica_Document(6, array('name' => 'mike', 'paid' => 15)); $type->addDocument($doc); $facet = new Elastica_Facet_TermsStats('test'); $facet->setKeyField('name'); $facet->setValueField('paid'); $query = new Elastica_Query(); $query->addFacet($facet); $query->setQuery(new Elastica_Query_MatchAll()); $index->refresh(); $response = $type->search($query); $facets = $response->getFacets(); $this->assertEquals(2, count($facets['test']['terms'])); foreach ($facets['test']['terms'] as $facet) { if ($facet['term'] === 'tom') { $this->assertEquals(14, $facet['total']); } if ($facet['term'] === 'mike') { $this->assertEquals(29, $facet['total']); } } }
public function search($query) { if (is_string($query)) { $queryObj = new Query(); $queryObj->setQuery($query); $query = $queryObj; } if ($query instanceof QueryInterface) { $query->setIndexManager($this); // Build the Elastica Query $elasticaQuery = new \Elastica_Query(); // Define a Query. We want a string query. $elasticaQueryString = new \Elastica_Query_QueryString(); $elasticaQueryString->setDefaultOperator('AND'); $elasticaQueryString->setQuery($query->getQuery()); $elasticaQuery->setQuery($elasticaQueryString); $elasticaQuery->setFrom($query->getOffset()); $elasticaQuery->setLimit($query->getLimit()); $index = $this->getIndex(); $elasticaResultSet = $index->search($elasticaQuery); return $elasticaResultSet; } throw new \InvalidArgumentException(); }
} $idx = $_REQUEST['idx']; $type = $_REQUEST['type']; $query = str_replace('\\', '', $_REQUEST['query']); $idx_type = $idx; if ('' !== $type) { $idx_type .= '/' . $type; } //OPTIONAL: uncomment to enable whitelisting //if ( ! in_array( $idx_type, array_keys( $whitelist_idx ) ) ) { // status_header( 403 ); //forbidden // die; //} try { $esclient = new Elastica_Client(array('servers' => $es_servers)); $esQ = new Elastica_Query(); $esQ->setRawQuery(get_object_vars(json_decode($query))); if (isset($whitelist_idx[$idx_type])) { $esQ->setHighlight(array('fields' => $whitelist_idx[$idx_type]['highlight'], 'pre_tags' => array('<b>'), 'post_tags' => array('</b>'))); $esQ->setFields($whitelist_idx[$idx_type]['fields']); } if ('' != $type) { $estype = $esclient->getIndex($idx)->getType($type); } else { $estype = $esclient->getIndex($idx); } $results = $estype->search($esQ); echo json_encode($results->getResponse()->getData()); } catch (Exception $e) { error_log($e->getMessage()); status_header(500);
public function testGetQuery() { $query = new Elastica_Query(); try { $query->getQuery(); $this->fail('should throw exception because query does not exist'); } catch(Elastica_Exception_Invalid $e) { $this->assertTrue(true); } $termQuery = new Elastica_Query_Term(); $termQuery->setTerm('text', 'value'); $query->setQuery($termQuery); $this->assertEquals($termQuery->toArray(), $query->getQuery()); }
/** * Search in the set indices, types * * @param mixed $query * @return Elastica_ResultSet */ public function search($query) { $query = Elastica_Query::create($query); $path = $this->getPath(); $response = $this->getClient()->request($path, Elastica_Request::GET, $query->toArray()); return new Elastica_ResultSet($response); }
/** * Registers a percolator query * * @param string $name Query name * @param string|Elastica_Query|Elastica_Query_Abstract $query Query to add * @return Elastica_Response */ public function registerQuery($name, $query) { $path = '_percolator/' . $this->_index->getName() . '/' . $name; $query = Elastica_Query::create($query); return $this->_index->getClient()->request($path, Elastica_Request::PUT, $query->toArray()); }
/** * Search method. * * @return Elastica_ResultSet */ public function search() { $index = $this->index; // build search query $query = new \Elastica_Query(); $query->setQuery($this->getQuery()); $query->addFacet($this->getFacet('class')); $query->addFacet($this->getFacet('family')); $query->addFacet($this->getFacet('town')); $query->addFacet($this->getFacet('canton')); $query->addFacet($this->getFacet('user')); $query->addFacet($this->getFacet('habitat')); $query->addFacet($this->getFacet('redlist')); $query->addFacet($this->getFacet('image_type')); $query->setSize(100); // sorting if (count($this->sort) > 0) { $query->setSort($this->sort); } // add filter to query $filter = $this->getFilter(); if (count($filter->getParams()) > 0) { $query->setFilter($filter); } $result = $this->getType()->search($query); return $result; }
public function testSetTypeArraySearchSingle() { $filter = new Elastica_Filter_Ids(); $filter->setIds('4'); $filter->setType(array('helloworld1', 'helloworld2')); $query = Elastica_Query::create($filter); $resultSet = $this->_index->search($query); $this->assertEquals(2, $resultSet->count()); }
/** * Search in the set indices, types * * @param mixed $query * @param int|array $options OPTIONAL Limit or associative array of options (option=>value) * @return Elastica_ResultSet */ public function search($query, $options = null) { $query = Elastica_Query::create($query); $path = $this->getPath(); $params = array(); if (is_int($options)) { $query->setLimit($options); } else { if (is_array($options)) { foreach ($options as $key => $value) { switch ($key) { case 'limit': $query->setLimit($value); break; case 'routing': $params['routing'] = $value; break; case 'search_type': $params['search_type'] = $value; break; default: throw new Elastica_Exception_Invalid('Invalid option ' . $key); break; } } } } $response = $this->getClient()->request($path, Elastica_Request::GET, $query->toArray(), $params); return new Elastica_ResultSet($response); }
/** * More like this query based on the given object * * The id in the given object has to be set * * @param Elastica_Document $doc Document to query for similar objects * @param array $params OPTIONAL Additional arguments for the query * @param Elastica_Query $query OPTIONAL Query to filter the moreLikeThis results * @return Elastica_ResultSet ResultSet with all results inside * @link http://www.elasticsearch.org/guide/reference/api/more-like-this.html */ public function moreLikeThis(Elastica_Document $doc, $params = array(), $query = array()) { $path = $doc->getId() . '/_mlt'; $query = Elastica_Query::create($query); $response = $this->request($path, Elastica_Request::GET, $query->toArray(), $params); return new Elastica_ResultSet($response); }
/** * {@inheritDoc} */ public function count($query) { $query = Elastica_Query::create($query); $path = '_count'; $data = $this->request($path, Elastica_Request::GET, $query->getQuery())->getData(); return (int) $data['count']; }
/** * Search in the set indices, types * * @param mixed $query * @param int|array $options OPTIONAL Limit or associative array of options (option=>value) * @return Elastica_ResultSet */ public function search($query, $options = null) { $query = Elastica_Query::create($query); $path = $this->getPath(); if (is_int($options)) { $query->setLimit($options); } else { if (is_array($options)) { foreach ($options as $key => $value) { if (empty($value)) { throw new Elastica_Exception_Invalid('Invalid value ' . $value . ' for option ' . $key); } else { $path_separator = strpos($path, '?') ? '&' : '?'; switch ($key) { case 'limit': $query->setLimit($value); break; case 'routing': if (!empty($value)) { $path .= $path_separator . 'routing=' . $value; } break; case 'search_type': if (!empty($value)) { $path .= $path_separator . 'search_type=' . $value; } break; default: throw new Elastica_Exception_Invalid('Invalid option ' . $key); break; } } } } } $response = $this->getClient()->request($path, Elastica_Request::GET, $query->toArray()); return new Elastica_ResultSet($response); }
public function grab(&$param_pool = NULL) { $config = (object) Symphony::Configuration()->get('elasticsearch'); // build an object of runtime parameters $params = (object) array('keywords' => isset($_GET['keywords']) ? $_GET['keywords'] : '', 'current-page' => isset($_GET['page']) && is_numeric($_GET['page']) ? (int) $_GET['page'] : 1, 'per-page' => isset($_GET['per-page']) && is_numeric($_GET['per-page']) ? (int) $_GET['per-page'] : $config->{'per-page'}, 'sort' => isset($_GET['sort']) ? $_GET['sort'] : $config->sort, 'direction' => isset($_GET['direction']) && in_array($_GET['direction'], array('asc', 'desc')) ? $_GET['direction'] : $config->direction, 'sections' => isset($_GET['sections']) && !empty($_GET['sections']) ? array_map('trim', explode(',', $_GET['sections'])) : NULL, 'default-sections' => !empty($config->{'default-sections'}) ? explode(',', $config->{'default-sections'}) : NULL, 'language' => isset($_GET['language']) && !empty($_GET['language']) ? array_map('trim', explode(',', $_GET['language'])) : NULL, 'default-language' => !empty($config->{'default-language'}) ? explode(',', $config->{'default-language'}) : NULL); $params->{'keywords-raw'} = $params->keywords; $params->keywords = ElasticSearch::filterKeywords($params->keywords); // don't run search if not searching for anything if (empty($params->keywords)) { return; } // check valid page number if ($params->{'current-page'} < 1) { $params->{'current-page'} = 1; } // if no language passed but there are defaults, use the defaults if ($params->{'language'} === NULL && count($params->{'default-language'})) { $params->{'language'} = $params->{'default-language'}; } // include this extension's own library ElasticSearch::init(); // a query_string search type in ES accepts common (Lucene) search syntax such as // prefixing terms with +/- and surrounding exact phrases with quotes $query_querystring = new Elastica_Query_QueryString(); // all terms are required $query_querystring->setDefaultOperator('AND'); // pass in keywords $query_querystring->setQueryString($params->keywords); // only apply the search to fields mapped as multi-type with a sub-type named "symphony_fulltext" // this allows us to exclude fields from this generic full-site search but search them elsewhere if ($params->{'language'}) { $fields = array(); foreach ($params->{'language'} as $language) { $fields[] = '*_' . $language . '.symphony_fulltext'; } $query_querystring->setFields($fields); } else { $query_querystring->setFields(array('*.symphony_fulltext')); } // create the parent query object (a factory) into which the query_string is passed $query = new Elastica_Query($query_querystring); $query->setLimit($params->{'per-page'}); // TODO: check this. should it be + 1? $query->setFrom($params->{'per-page'} * ($params->{'current-page'} - 1)); $query->setSort(array($params->{'sort'} => $params->{'direction'})); // build a search object, this wraps an Elastica_Client and handles requests to and from the ElasticSearch server $search = new Elastica_Search(ElasticSearch::getClient()); // search on our site index only (in case the server is running multiple indexes) $search->addIndex(ElasticSearch::getIndex()); // create a new facet on the entry _type (section handle). this will return a list // of sections in which the matching entries reside, and a count of matches in each $facet = new Elastica_Facet_Terms('filtered-sections'); $facet->setField('_type'); $query->addFacet($facet); // we also want a list of _all_ sections and their total entry counts. facets run within the context // of the query they are attached to, so we want a new query that searches within the specified sections // but doesn't search on the keywords (so it finds everything). ES supports this with a match_all query // which Elastica creates by default when you create a plain query object $query_all = new Elastica_Query(); $facet = new Elastica_Facet_Terms('all-sections'); $facet->setField('_type'); $query_all->addFacet($facet); // build an array of all valid section handles that have mappings $all_mapped_sections = array(); $section_full_names = array(); foreach (ElasticSearch::getAllTypes() as $type) { // if using default config sections, check that the type exists in the default if (count($params->{'default-sections'}) > 0 && !in_array($type->section->get('handle'), $params->{'default-sections'})) { continue; } $all_mapped_sections[] = $type->section->get('handle'); // cache an array of section names indexed by their handles, quick lookup later $section_full_names[$type->section->get('handle')] = $type->section->get('name'); } $sections = array(); // no specified sections were sent in the params, so default to all available sections if ($params->sections === NULL) { $sections = $all_mapped_sections; } else { foreach ($params->sections as $handle) { if (!in_array($handle, $all_mapped_sections)) { continue; } $sections[] = $handle; } } // a filter is an additional set of filtering that can be added to a query. filters are run // after the query has executed, so run over the resultset and remove documents that don't // match the criteria. they are fast and are cached by ES. we want to restrict the search // results to within the specified sections only, so we add a filter on the _type (section handle) // field. the filter is of type "terms" (an array of exact-match strings) $filter = new Elastica_Filter_Terms('_type'); // build an array of field handles which should be highlighted in search results, used for building // the excerpt on results pages. a field is marked as highlightable by giving it a "symphony_fulltext" // field in the section mappings $highlights = array(); // iterate over each valid section, adding it as a filter and finding any highlighted fields within foreach ($sections as $section) { // add these sections to the entry search $filter->addTerm($section); // read the section's mapping JSON from disk $mapping = json_decode(ElasticSearch::getTypeByHandle($section)->mapping_json, FALSE); // find fields that have symphony_highlight foreach ($mapping->{$section}->properties as $field => $properties) { if (!$properties->fields->symphony_fulltext) { continue; } $highlights[] = array($field => (object) array()); } } // add the section filter to both queries (keyword search and the all entries facet search) $query->setFilter($filter); $query_all->setFilter($filter); // configure highlighting for the keyword search $query->setHighlight(array('fields' => $highlights, 'encoder' => 'html', 'fragment_size' => $config->{'highlight-fragment-size'}, 'number_of_fragments' => $config->{'highlight-per-field'}, 'pre_tags' => array('<strong class="highlight">'), 'post_tags' => array('</strong>'))); // run both queries! $query_result = $search->search($query); $query_all_result = $search->search($query_all); // build root XMK element $xml = new XMLElement($this->dsParamROOTELEMENT, NULL, array('took' => $query_result->getResponse()->getEngineTime() . 'ms', 'max-score' => round($query_result->getMaxScore(), 4))); // append keywords to the XML $xml_keywords = new XMLElement('keywords'); $xml_keywords->appendChild(new XMLElement('raw', General::sanitize($params->{'keywords-raw'}))); $xml_keywords->appendChild(new XMLElement('filtered', General::sanitize($params->{'keywords'}))); $xml->appendChild($xml_keywords); // build pagination $xml->appendChild(General::buildPaginationElement($query_result->getTotalHits(), ceil($query_result->getTotalHits() * (1 / $params->{'per-page'})), $params->{'per-page'}, $params->{'current-page'})); // build facets $xml_facets = new XMLElement('facets'); // merge the facets from both queries so they appear as one $facets = array_merge($query_result->getFacets(), $query_all_result->getFacets()); foreach ($facets as $handle => $facet) { $xml_facet = new XMLElement('facet', NULL, array('handle' => $handle)); foreach ($facet['terms'] as $term) { // only show sections that are in default config, if it is being used if (!in_array($term['term'], $all_mapped_sections)) { continue; } $xml_facet_term = new XMLElement('term', $section_full_names[$term['term']], array('handle' => $term['term'], 'entries' => $term['count'], 'active' => in_array($term['term'], $sections) ? 'yes' : 'no')); $xml_facet->appendChild($xml_facet_term); } $xml_facets->appendChild($xml_facet); } $xml->appendChild($xml_facets); // if each entry is to have its full XML built and appended to the result, // create a new EntryManager for using later on if ($config->{'build-entry-xml'} === 'yes') { $em = new EntryManager(Frontend::instance()); $field_pool = array(); } // append entries $xml_entries = new XMLElement('entries'); foreach ($query_result->getResults() as $data) { $entry = new XMLElement('entry', NULL, array('id' => $data->getId(), 'section' => $data->getType(), 'score' => is_array($data->getScore()) ? reset($data->getScore()) : round($data->getScore(), 4))); // append field highlights foreach ($data->getHighlights() as $field => $highlight) { foreach ($highlight as $html) { $entry->appendChild(new XMLElement('highlight', $html, array('field' => $field))); } } // build and append entry data // this was pinched from Symphony's datasource class if ($config->{'build-entry-xml'} === 'yes') { $e = reset($em->fetch($data->getId())); $field_data = $e->getData(); foreach ($field_data as $field_id => $values) { if (!isset($field_pool[$field_id]) || !is_object($field_pool[$field_id])) { $field_pool[$field_id] = FieldManager::fetch($field_id); } $field_pool[$field_id]->appendFormattedElement($entry, $values, FALSE, NULL, $e->get('id')); } } $xml_entries->appendChild($entry); // put each entry ID into the param pool for chaining $param_pool['ds-elasticsearch'][] = $data->getId(); } $xml->appendChild($xml_entries); // log query if logging is enabled if ($config->{'log-searches'} === 'yes') { ElasticSearchLogs::save($params->keywords, $params->{'keywords-raw'}, $sections, $params->{'current-page'}, $query_result->getTotalHits()); } return $xml; }
/** * Sets query object * * @param string|Elastica_Query|Elastica_Query_Abstract $query * @return Elastica_Filter_HasChild Current object */ public function setQuery($query) { $query = Elastica_Query::create($query); $data = $query->toArray(); return $this->setParam('query', $data['query']); }
public function testMoreLikeThisApi() { $client = new Elastica_Client(array('persistent' => false)); $index = $client->getIndex('elastica_test'); $index->create(array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0)), true); $type = new Elastica_Type($index, 'mlt_test'); $type->addDocument(new Elastica_Document(1, array('visible' => true, 'name' => 'bruce wayne batman'))); $type->addDocument(new Elastica_Document(2, array('visible' => true, 'name' => 'bruce wayne'))); $type->addDocument(new Elastica_Document(3, array('visible' => false, 'name' => 'bruce wayne'))); $type->addDocument(new Elastica_Document(4, array('visible' => true, 'name' => 'batman'))); $type->addDocument(new Elastica_Document(5, array('visible' => false, 'name' => 'batman'))); $type->addDocument(new Elastica_Document(6, array('visible' => true, 'name' => 'superman'))); $type->addDocument(new Elastica_Document(7, array('visible' => true, 'name' => 'spiderman'))); $index->refresh(); $document = $type->getDocument(1); // Return all similar $resultSet = $type->moreLikeThis($document, array('min_term_freq' => '1', 'min_doc_freq' => '1')); $this->assertEquals(4, $resultSet->count()); // Return just the visible similar $query = new Elastica_Query(); $filterTerm = new Elastica_Filter_Term(); $filterTerm->setTerm('visible', true); $query->setFilter($filterTerm); $resultSet = $type->moreLikeThis($document, array('min_term_freq' => '1', 'min_doc_freq' => '1'), $query); $this->assertEquals(2, $resultSet->count()); }
/** * Counts results of query * * @param string|array|Elastica_Query $query Array with all query data inside or a Elastica_Query object * @return int number of documents matching the query * @see Elastica_Searchable::count */ public function count($query = '') { $query = Elastica_Query::create($query); $path = '_search'; $response = $this->request($path, Elastica_Request::GET, $query->toArray(), array('search_type' => 'count')); $resultSet = new Elastica_ResultSet($response); return $resultSet->getTotalHits(); }
/** * Deletes entries in the db based on a query * * @param Elastica_Query|string $query Query object * @link http://www.elasticsearch.org/guide/reference/api/delete-by-query.html */ public function deleteByQuery($query) { $query = Elastica_Query::create($query); return $this->request('_query', Elastica_Request::DELETE, $query->getQuery()); }