Replace the type inspector with a mapping registry to improve performances

This commit is contained in:
ornicar 2011-06-07 14:19:50 -07:00
parent 074c596994
commit 214250416a
7 changed files with 75 additions and 109 deletions

View file

@ -33,7 +33,7 @@ class PopulateCommand extends Command
$this->container->get('foq_elastica.reseter')->reset();
$output->writeln('Setting mappings');
$this->container->get('foq_elastica.mapping_setter')->setMappings();
$this->container->get('foq_elastica.mapping_registry')->applyMappings();
$output->writeln('Populating indexes');
$this->container->get('foq_elastica.populator')->populate(function($text) use ($output) {

View file

@ -48,7 +48,7 @@ class FOQElasticaExtension extends Extension
}, $indexIdsByName);
$this->loadIndexManager($indexDefsByName, $container->getDefinition($indexIdsByName[$config['default_index']]), $container);
$this->loadMappingSetter($this->typeMappings, $container);
$this->loadMappingRegistry($this->typeMappings, $container);
$container->setAlias('foq_elastica.client', sprintf('foq_elastica.client.%s', $config['default_client']));
$container->setAlias('foq_elastica.index', sprintf('foq_elastica.index.%s', $config['default_index']));
@ -123,8 +123,9 @@ class FOQElasticaExtension extends Extension
$typeDef->setFactoryService($indexId);
$typeDef->setFactoryMethod('getType');
$container->setDefinition($typeId, $typeDef);
$key = sprintf('%s/%s', $indexName, $name);
if (isset($type['mappings'])) {
$this->typeMappings[] = array(new Reference($typeId), $type['mappings']);
$this->typeMappings[$key] = array(new Reference($typeId), $type['mappings']);
}
if (isset($type['doctrine'])) {
$this->loadTypeDoctrineIntegration($type['doctrine'], $container, $typeDef, $indexName, $name);
@ -223,7 +224,6 @@ class FOQElasticaExtension extends Extension
$serviceDef->replaceArgument(0, $typeDef);
$serviceDef->replaceArgument(1, new Reference($transformerId));
$serviceDef->replaceArgument(2, $typeConfig['model']);
$serviceDef->replaceArgument(3, new Reference('foq_elastica.type_inspector'));
$container->setDefinition($serviceId, $serviceDef);
return $serviceId;
@ -305,13 +305,13 @@ class FOQElasticaExtension extends Extension
}
/**
* Loads the mapping setter
* Loads the mapping registry
*
* @return null
**/
protected function loadMappingSetter(array $mappings, ContainerBuilder $container)
protected function loadMappingRegistry(array $mappings, ContainerBuilder $container)
{
$managerDef = $container->getDefinition('foq_elastica.mapping_setter');
$managerDef = $container->getDefinition('foq_elastica.mapping_registry');
$managerDef->replaceArgument(0, $mappings);
}

61
MappingRegistry.php Normal file
View file

@ -0,0 +1,61 @@
<?php
namespace FOQ\ElasticaBundle;
use Elastica_Type;
use InvalidArgumentException;
/**
* Stores the configured mappings for all types
* Responsible for applying configured mappings to elastica types
*/
class MappingRegistry
{
/**
* Configured mappings. See http://www.elasticsearch.org/guide/reference/mapping/
* array(
* "index_name/type_name" => array(type_object, mapping_array)
* )
*
* @var array
*/
protected $mappings = null;
/**
* Instanciates a new MappingSetter
*
* @param array mappings
*/
public function __construct($mappings)
{
$this->mappings = $mappings;
}
/**
* Apply mappings to all elastica types
**/
public function applyMappings()
{
foreach ($this->mappings as $pair) {
list($type, $mappings) = $pair;
$type->setMapping($mappings);
}
}
/**
* Gets the type mapping field names
*
* @param Elastica_Type $type
* @return array list of fields names
*/
public function getTypeFieldNames(Elastica_Type $type)
{
$key = sprintf('%s/%s', $type->getIndex()->getName(), $type->getType());
if (!isset($this->mappings[$key])) {
throw new InvalidArgumentException(sprintf('This type is not registered: "%s".', $key));
}
return array_keys($this->mappings[$key][1]);
}
}

View file

@ -1,39 +0,0 @@
<?php
namespace FOQ\ElasticaBundle;
/**
* Responsible for applying configured mappings to elastica types
*/
class MappingSetter
{
/**
* Configured mappings. See http://www.elasticsearch.org/guide/reference/mapping/
*
* @var array
*/
protected $mappings = null;
/**
* Instanciates a new MappingSetter
*
* @param array mappings
*/
public function __construct($mappings)
{
$this->mappings = $mappings;
}
/**
* Apply mappings to all elastica types
*
* @return null
**/
public function setMappings()
{
foreach ($this->mappings as $pair) {
list($type, $mappings) = $pair;
$type->setMapping($mappings);
}
}
}

View file

@ -4,7 +4,7 @@ namespace FOQ\ElasticaBundle\Persister;
use FOQ\ElasticaBundle\Provider\ProviderInterface;
use FOQ\ElasticaBundle\Transformer\ModelToElasticaTransformerInterface;
use FOQ\ElasticaBundle\TypeInspector;
use FOQ\ElasticaBundle\MappingRegistry;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Elastica_Type;
use Elastica_Document;
@ -21,17 +21,16 @@ class ObjectPersister implements ObjectPersisterInterface
protected $type;
protected $transformer;
protected $objectClass;
protected $typeInspector;
protected $mappingRegistry;
protected $logger;
protected $throwExceptions;
protected $fields;
public function __construct(Elastica_Type $type, ModelToElasticaTransformerInterface $transformer, $objectClass, TypeInspector $typeInspector, LoggerInterface $logger = null, $throwExceptions = true)
public function __construct(Elastica_Type $type, ModelToElasticaTransformerInterface $transformer, $objectClass, MappingRegistry $mappingRegistry, LoggerInterface $logger = null, $throwExceptions = true)
{
$this->type = $type;
$this->transformer = $transformer;
$this->objectClass = $objectClass;
$this->typeInspector = $typeInspector;
$this->mappingRegistry = $mappingRegistry;
$this->logger = $logger;
$this->throwExceptions = true;
}
@ -111,21 +110,7 @@ class ObjectPersister implements ObjectPersisterInterface
*/
protected function transformToElasticaDocument($object)
{
return $this->transformer->transform($object, $this->getTypeFields());
}
/**
* Gets the list of the type fields
*
* @return array of strings
*/
protected function getTypeFields()
{
if (null === $this->fields) {
$this->fields = $this->typeInspector->getMappingFieldsNames($this->type);
}
return $this->fields;
return $this->transformer->transform($object, $this->mappingRegistry->getTypeFieldNames($this->type));
}
/**

View file

@ -26,17 +26,15 @@
<argument type="service" id="foq_elastica.index_manager" />
</service>
<service id="foq_elastica.mapping_setter" class="FOQ\ElasticaBundle\MappingSetter">
<service id="foq_elastica.mapping_registry" class="FOQ\ElasticaBundle\MappingRegistry">
<argument /> <!-- mappings -->
</service>
<service id="foq_elastica.type_inspector" class="FOQ\ElasticaBundle\TypeInspector" public="false" />
<service id="foq_elastica.object_persister.prototype" class="FOQ\ElasticaBundle\Persister\ObjectPersister" public="false" abstract="true">
<argument /> <!-- type -->
<argument /> <!-- model to elastica transformer -->
<argument /> <!-- model -->
<argument /> <!-- type inspector -->
<argument type="service" id="foq_elastica.mapping_registry" />
<argument type="service" id="logger" on-invalid="null" />
<argument>%kernel.debug%</argument>
</service>

View file

@ -1,39 +0,0 @@
<?php
namespace FOQ\ElasticaBundle;
use Elastica_Type;
/**
* Extracts the mapping fields from a type
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
*/
class TypeInspector
{
/**
* Gets the type mapping fields
*
* @param Elastica_Type $type
* @return array list of fields names
*/
public function getMappingFieldsNames(Elastica_Type $type)
{
$mappings = $type->getMapping();
// skip index and type name
// < 0.16.0 has both index and type levels
// >= 0.16.0 has only type level
do {
$mappings = reset($mappings);
} while (is_array($mappings) && !isset($mappings['properties']));
if (!isset($mappings['properties'])) {
return array();
}
$mappings = $mappings['properties'];
if (array_key_exists('__isInitialized__', $mappings)) {
unset($mappings['__isInitialized__']);
}
return array_keys($mappings);
}
}