/** * Reindex documents from an old index to a new index. * * @link https://www.elastic.co/guide/en/elasticsearch/guide/master/reindex.html * * @param \Elastica\Index $oldIndex * @param \Elastica\Index $newIndex * @param array $options keys: CrossIndex::OPTION_* constants * * @return \Elastica\Index The new index object */ public static function reindex(Index $oldIndex, Index $newIndex, array $options = array()) { // prepare search $search = new Search($oldIndex->getClient()); $options = array_merge(array(self::OPTION_TYPE => null, self::OPTION_QUERY => new MatchAll(), self::OPTION_EXPIRY_TIME => '1m', self::OPTION_SIZE_PER_SHARD => 1000), $options); $search->addIndex($oldIndex); if (isset($options[self::OPTION_TYPE])) { $type = $options[self::OPTION_TYPE]; $search->addTypes(is_array($type) ? $type : array($type)); } $search->setQuery($options[self::OPTION_QUERY]); // search on old index and bulk insert in new index $scanAndScroll = new ScanAndScroll($search, $options[self::OPTION_EXPIRY_TIME], $options[self::OPTION_SIZE_PER_SHARD]); foreach ($scanAndScroll as $resultSet) { $bulk = new Bulk($newIndex->getClient()); $bulk->setIndex($newIndex); foreach ($resultSet as $result) { $action = new Bulk\Action(); $action->setType($result->getType()); $action->setId($result->getId()); $action->setSource($result->getData()); $bulk->addAction($action); } $bulk->send(); } $newIndex->refresh(); return $newIndex; }
/** * Get health information about the index * @return array Response data array */ private function getHealth() { while (true) { $indexName = $this->index->getName(); $path = "_cluster/health/{$indexName}"; $response = $this->index->getClient()->request($path); if ($response->hasError()) { $this->error('Error fetching index health but going to retry. Message: ' . $response->getError()); sleep(1); continue; } return $response->getData(); } }
/** * @param Index $index * @param \ElasticaConnection $connection * @param Type[] $types * @param Type[] $oldTypes * @param int $shardCount * @param string $replicaCount * @param int $connectionTimeout * @param array $mergeSettings * @param array $mappingConfig * @param Maintenance $out */ public function __construct(Index $index, \ElasticaConnection $connection, array $types, array $oldTypes, $shardCount, $replicaCount, $connectionTimeout, array $mergeSettings, array $mappingConfig, Maintenance $out = null) { // @todo: this constructor has too many arguments - refactor! $this->index = $index; $this->client = $this->index->getClient(); $this->specificIndexName = $this->index->getName(); $this->connection = $connection; $this->types = $types; $this->oldTypes = $oldTypes; $this->shardCount = $shardCount; $this->replicaCount = $replicaCount; $this->connectionTimeout = $connectionTimeout; $this->mergeSettings = $mergeSettings; $this->mappingConfig = $mappingConfig; $this->out = $out; }
public function testMatchDoc() { $client = new Client(array('persistent' => false)); $index = $client->getIndex('elastica_test'); $index->create(array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0)), true); $percolator = new Percolator($index); $percolatorName = 'percotest'; $query = new Term(array('name' => 'ruflin')); $response = $percolator->registerQuery($percolatorName, $query); $this->assertTrue($response->isOk()); $this->assertFalse($response->hasError()); $doc1 = new Document(); $doc1->set('name', 'ruflin'); $doc2 = new Document(); $doc2->set('name', 'nicolas'); $index = new Index($index->getClient(), '_percolator'); $index->optimize(); $index->refresh(); $matches1 = $percolator->matchDoc($doc1); $this->assertTrue(in_array($percolatorName, $matches1)); $this->assertEquals(1, count($matches1)); $matches2 = $percolator->matchDoc($doc2); $this->assertEmpty($matches2); }
protected function _waitForAllocation(Index $index) { do { $state = $index->getClient()->getCluster()->getState(); $indexState = $state['routing_table']['indices'][$index->getName()]; $allocated = true; foreach ($indexState['shards'] as $shard) { if ($shard[0]['state'] != 'STARTED') { $allocated = false; } } } while (!$allocated); }
/** * Removes a percolator query. * * @param string $name query name * * @return \Elastica\Response */ public function unregisterQuery($name) { $path = $this->_index->getName() . '/.percolator/' . $name; return $this->_index->getClient()->request($path, Request::DELETE); }
/** * 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) { } } }