Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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