Skip to content

Commit

Permalink
Merge pull request #194 from martiis/issue-170
Browse files Browse the repository at this point in the history
Commands for manipulating with type's
  • Loading branch information
saimaz committed Feb 25, 2015
2 parents 9ac4ade + c719c5b commit 2654596
Show file tree
Hide file tree
Showing 17 changed files with 839 additions and 353 deletions.
208 changes: 158 additions & 50 deletions Client/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,10 @@ public function scroll($scrollId, $scrollDuration)
*/
public function createIndex($putWarmers = false)
{
$this->client->indices()->create($this->settings);
$settings = $this->settings;
unset($settings['body']['mappings']);

$this->client->indices()->create($settings);

if ($putWarmers) {
// Sometimes Elasticsearch gives service unavailable.
Expand All @@ -238,6 +241,85 @@ public function dropIndex()
$this->client->indices()->delete(['index' => $this->getIndexName()]);
}

/**
* Puts mapping into elasticsearch client.
*
* @param array $types Specific types to put.
*
* @return int
*/
public function createTypes(array $types = [])
{
$mapping = $this->getMapping($types);
if (empty($mapping)) {
return 0;
}

$mapping = array_diff_key($mapping, $this->getMappingFromIndex($types));
if (empty($mapping)) {
return -1;
}

$this->loadMappingArray($mapping);

return 1;
}

/**
* Drops mapping from elasticsearch client.
*
* @param array $types Specific types to drop.
*
* @return int
*/
public function dropTypes(array $types = [])
{
$mapping = $this->getMapping($types);

if (empty($mapping)) {
return 0;
}

$this->unloadMappingArray(array_keys($mapping));

return 1;
}

/**
* Updates elasticsearch client mapping.
*
* @param array $types Specific types to update.
*
* @return int
*/
public function updateTypes(array $types = [])
{
if (!$this->getMapping($types)) {
return -1;
}

$tempSettings = $this->settings;
$tempSettings['index'] = uniqid('mapping_check_');
$mappingCheckConnection = new Connection($this->client, $tempSettings);
$mappingCheckConnection->createIndex();
$mappingCheckConnection->createTypes($types);

$newMapping = $mappingCheckConnection->getMappingFromIndex($types);
$oldMapping = $this->getMappingFromIndex($types);

$mappingCheckConnection->dropIndex();

$tool = new MappingTool();
$updated = (int)$tool->checkMapping($oldMapping, $newMapping);

if ($updated) {
$this->unloadMappingArray($tool->getRemovedTypes());
$this->loadMappingArray($tool->getUpdatedTypes());
}

return $updated;
}

/**
* Tries to drop and create fresh elasticsearch index.
*
Expand Down Expand Up @@ -285,18 +367,16 @@ public function setIndexName($name)
}

/**
* Returns mapping by type.
* Returns mapping by type if defined.
*
* @param string $type Type name.
* @param string|array $type Type names.
*
* @return array|null
*/
public function getMapping($type)
public function getMapping($type = [])
{
if (isset($this->settings['body']['mappings'])
&& array_key_exists($type, $this->settings['body']['mappings'])
) {
return $this->settings['body']['mappings'][$type];
if (isset($this->settings['body']['mappings'])) {
return $this->filterMapping($type, $this->settings['body']['mappings']);
}

return null;
Expand Down Expand Up @@ -343,49 +423,17 @@ public function setMultipleMapping(array $mapping, $cleanUp = false)
/**
* Mapping is compared with loaded, if needed updates it and returns true.
*
* @param array $types Types to update.
*
* @return bool
*
* @throws \LogicException
*
* @deprecated Will be removed in 1.0. Please now use Connection#updateTypes()
*/
public function updateMapping()
public function updateMapping(array $types = [])
{
if (!isset($this->settings['body']['mappings']) || empty($this->settings['body']['mappings'])) {
throw new \LogicException('Connection does not have any mapping loaded.');
}

$tempSettings = $this->settings;
$tempSettings['index'] = uniqid('mapping_check_');
$mappingCheckConnection = new Connection($this->client, $tempSettings);
$mappingCheckConnection->createIndex();

$newMapping = $mappingCheckConnection->getMappingFromIndex();
$oldMapping = $this->getMappingFromIndex();

$mappingCheckConnection->dropIndex();

$tool = new MappingTool();
$updated = $tool->checkMapping($oldMapping, $newMapping);

if ($updated) {
foreach ($tool->getRemovedTypes() as $type) {
$this->client->indices()->deleteMapping(
[
'index' => $this->getIndexName(),
'type' => $type,
]
);
}
foreach ($tool->getUpdatedTypes() as $type => $properties) {
$this->client->indices()->putMapping(
[
'index' => $this->getIndexName(),
'type' => $type,
'body' => [$type => $properties],
]
);
}
}

return $updated;
return $this->updateTypes($types);
}

/**
Expand Down Expand Up @@ -423,17 +471,19 @@ public function open()
/**
* Returns mapping from index.
*
* @param array|string $types Returns only certain set of types if set.
*
* @return array
*/
public function getMappingFromIndex()
public function getMappingFromIndex($types = [])
{
$mapping = $this
->client
->indices()
->getMapping(['index' => $this->getIndexName()]);

if (array_key_exists($this->getIndexName(), $mapping)) {
return $mapping[$this->getIndexName()]['mappings'];
return $this->filterMapping($types, $mapping[$this->getIndexName()]['mappings']);
}

return [];
Expand Down Expand Up @@ -465,7 +515,7 @@ public function updateSettings(array $settings, $force = false)
}

/**
* Clears elasticsearch cache.
* Clears elasticsearch client cache.
*/
public function clearCache()
{
Expand Down Expand Up @@ -577,4 +627,62 @@ private function validateWarmers($names, $warmerNames = [])
);
}
}

/**
* Puts mapping into elasticsearch.
*
* @param array $mapping Mapping to put into client.
*/
private function loadMappingArray(array $mapping)
{
foreach ($mapping as $type => $properties) {
$this->client->indices()->putMapping(
[
'index' => $this->getIndexName(),
'type' => $type,
'body' => [
$type => $properties,
],
]
);
}
}

/**
* Drops mapping from elasticsearch client.
*
* @param array $mapping Mapping to drop from client.
*/
private function unloadMappingArray(array $mapping)
{
foreach ($mapping as $type) {
$this->client->indices()->deleteMapping(
[
'index' => $this->getIndexName(),
'type' => $type,
]
);
}
}

/**
* Filters out mapping from given type.
*
* @param string|array $type Types to filter from mapping.
* @param array $mapping Mapping array.
*
* @return array
*/
private function filterMapping($type, $mapping)
{
if (empty($type)) {
return $mapping;
} elseif (is_string($type) && array_key_exists($type, $mapping)) {
return $mapping[$type];
} elseif (is_array($type)) {
return array_intersect_key($mapping, array_flip($type));
}

return [];
}
}
22 changes: 12 additions & 10 deletions Command/AbstractManagerAwareCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ protected function configure()
}

/**
* Returns elasticsearch manager by name with latest mappings.
* Returns elasticsearch manager by name from service container.
*
* @param string $name
* @param string $name Manager name defined in configuration.
*
* @return Manager
*
* @throws \RuntimeException
* @throws \RuntimeException If manager was not found.
*/
protected function getManager($name)
{
Expand All @@ -53,21 +53,23 @@ protected function getManager($name)
}

throw new \RuntimeException(
sprintf('Manager named `%s` not found. Check your configuration.', $name)
sprintf(
'Manager named `%s` not found. Available: `%s`.',
$name,
implode('`, `', array_keys($this->getContainer()->getParameter('es.managers')))
)
);
}

/**
* Returns connection service id.
* Formats manager service id from its name.
*
* @param string $name
* @param string $name Manager name.
*
* @return string
* @return string Service id.
*/
private function getManagerId($name)
{
$manager = $name == 'default' || empty($name) ? 'es.manager' : sprintf('es.manager.%s', $name);

return $manager;
return sprintf('es.manager.%s', $name);
}
}
11 changes: 9 additions & 2 deletions Command/IndexDropCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ protected function configure()
->setDescription('Drops elasticsearch index.')
->addOption(
'force',
null,
'f',
InputOption::VALUE_NONE,
'Set this parameter to execute this command'
);
Expand All @@ -54,7 +54,14 @@ protected function execute(InputInterface $input, OutputInterface $output)
)
);
} else {
$output->writeln('<info>Parameter --force has to be used to drop the index.</info>');
$output->writeln(
'<error>ATTENTION:</error> This action should not be used in production environment.'
. "\n\nOption --force has to be used to drop type(s)."
);

return 1;
}

return 0;
}
}
Loading

0 comments on commit 2654596

Please sign in to comment.