diff --git a/DataCollector/ElasticaDataCollector.php b/DataCollector/ElasticaDataCollector.php index 27736af..2eb3146 100644 --- a/DataCollector/ElasticaDataCollector.php +++ b/DataCollector/ElasticaDataCollector.php @@ -40,6 +40,16 @@ class ElasticaDataCollector extends DataCollector return $this->data['queries']; } + public function getTime() + { + $time = 0; + foreach ($this->data['queries'] as $query) { + $time += $query['executionMS']; + } + + return $time; + } + /** * {@inheritdoc} */ diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 928c777..8bf692c 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -108,6 +108,7 @@ class Configuration ->prototype('array') ->performNoDeepMerging() ->children() + ->scalarNode('index_name')->end() ->scalarNode('client')->end() ->scalarNode('finder') ->treatNullLike(true) @@ -253,6 +254,7 @@ class Configuration ->append($this->getMappingsNode()) ->append($this->getSourceNode()) ->append($this->getBoostNode()) + ->append($this->getRoutingNode()) ->end() ; @@ -403,6 +405,9 @@ class Configuration ->useAttributeAsKey('name') ->prototype('scalar')->end() ->end() + ->scalarNode('compress')->end() + ->scalarNode('compress_threshold')->end() + ->scalarNode('enabled')->end() ->end() ; @@ -426,4 +431,22 @@ class Configuration return $node; } + + /** + * Returns the array node used for "_routing". + */ + protected function getRoutingNode() + { + $builder = new TreeBuilder(); + $node = $builder->root('_routing'); + + $node + ->children() + ->scalarNode('required')->end() + ->scalarNode('path')->end() + ->end() + ; + + return $node; + } } diff --git a/DependencyInjection/FOQElasticaExtension.php b/DependencyInjection/FOQElasticaExtension.php index fb1d86d..f1a0c69 100644 --- a/DependencyInjection/FOQElasticaExtension.php +++ b/DependencyInjection/FOQElasticaExtension.php @@ -105,7 +105,8 @@ class FOQElasticaExtension extends Extension $clientId = $clientIdsByName[$clientName]; $indexId = sprintf('foq_elastica.index.%s', $name); - $indexDefArgs = array($name); + $indexName = isset($index['index_name']) ? $index['index_name'] : $name; + $indexDefArgs = array($indexName); $indexDef = new Definition('%foq_elastica.index.class%', $indexDefArgs); $indexDef->setFactoryService($clientId); $indexDef->setFactoryMethod('getIndex'); @@ -178,6 +179,9 @@ class FOQElasticaExtension extends Extension if (isset($type['_boost'])) { $this->indexConfigs[$indexName]['config']['mappings'][$name]['_boost'] = $type['_boost']; } + if (isset($type['_routing'])) { + $this->indexConfigs[$indexName]['config']['mappings'][$name]['_routing'] = $type['_routing']; + } if (isset($type['mappings'])) { $this->indexConfigs[$indexName]['config']['mappings'][$name]['properties'] = $type['mappings']; $typeName = sprintf('%s/%s', $indexName, $name); @@ -368,15 +372,16 @@ class FOQElasticaExtension extends Extension protected function loadTypeFinder(array $typeConfig, ContainerBuilder $container, $elasticaToModelId, $typeDef, $indexName, $typeName) { if (isset($typeConfig['finder']['service'])) { - return $typeConfig['finder']['service']; + $finderId = $typeConfig['finder']['service']; + } else { + $abstractFinderId = 'foq_elastica.finder.prototype'; + $finderId = sprintf('foq_elastica.finder.%s.%s', $indexName, $typeName); + $finderDef = new DefinitionDecorator($abstractFinderId); + $finderDef->replaceArgument(0, $typeDef); + $finderDef->replaceArgument(1, new Reference($elasticaToModelId)); + $container->setDefinition($finderId, $finderDef); } - $abstractFinderId = 'foq_elastica.finder.prototype'; - $finderId = sprintf('foq_elastica.finder.%s.%s', $indexName, $typeName); - $finderDef = new DefinitionDecorator($abstractFinderId); - $finderDef->replaceArgument(0, $typeDef); - $finderDef->replaceArgument(1, new Reference($elasticaToModelId)); - $container->setDefinition($finderId, $finderDef); - + $managerId = sprintf('foq_elastica.manager.%s', $typeConfig['driver']); $managerDef = $container->getDefinition($managerId); $arguments = array( $typeConfig['model'], new Reference($finderId)); diff --git a/README.md b/README.md index 5afd398..131b1b4 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,21 @@ Here we created a "website" index, that uses our "default" client. Our index is now available as a service: `foq_elastica.index.website`. It is an instance of `Elastica_Index`. +If you need to have different index name from the service name, for example, +in order to have different indexes for different environments then you can +use the ```index_name``` key to change the index name. The service name will +remain the same across the environments: + + foq_elastica: + clients: + default: { host: localhost, port: 9200 } + indexes: + website: + client: default + index_name: website_qa + +The service id will be `foq_elastica.index.website` but the underlying index name is website_qa. + #### Declare a type Elasticsearch type is comparable to Doctrine entity repository. @@ -395,7 +410,7 @@ example: $repository = $repositoryManager->getRepository('UserBundle:User'); /** var array of Acme\UserBundle\Entity\User */ - $users = $finder->find('bob'); + $users = $repository->find('bob'); You can also specify the full name of the entity instead of the shortcut syntax: @@ -416,7 +431,7 @@ to `foq_elastica.manager`. So the above example could be simplified to: $repository = $repositoryManager->getRepository('UserBundle:User'); /** var array of Acme\UserBundle\Entity\User */ - $users = $finder->find('bob'); + $users = $repository->find('bob'); If you use multiple drivers then you can choose which one is aliased to `foq_elastica.manager` using the `default_manager` parameter: @@ -478,7 +493,7 @@ Then the custom queries will be available when using the repository returned fro $repository = $repositoryManager->getRepository('UserBundle:User'); /** var array of Acme\UserBundle\Entity\User */ - $users = $finder->findWithCustomQuery('bob'); + $users = $repository->findWithCustomQuery('bob'); Alternatively you can specify the custom repository using an annotation in the entity: diff --git a/Resources/views/Collector/elastica.html.twig b/Resources/views/Collector/elastica.html.twig index 972f581..f63e8cf 100644 --- a/Resources/views/Collector/elastica.html.twig +++ b/Resources/views/Collector/elastica.html.twig @@ -10,6 +10,10 @@ Queries {{ collector.querycount }} +
+ Query Time + {{ '%0.2f'|format(collector.time * 1000) }} ms +
{% endset %} {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %} {% endblock %} diff --git a/Tests/DataCollector/ElasticaDataCollectorTest.php b/Tests/DataCollector/ElasticaDataCollectorTest.php index b83a81c..7ec9800 100644 --- a/Tests/DataCollector/ElasticaDataCollectorTest.php +++ b/Tests/DataCollector/ElasticaDataCollectorTest.php @@ -60,4 +60,29 @@ class ElasticaDataCollectorTest extends \PHPUnit_Framework_TestCase $this->assertEquals($queries, $elasticaDataCollector->getQueries()); } + public function testCorrectQueriesTime() + { + $requestMock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request') + ->disableOriginalConstructor() + ->getMock(); + + $responseMock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Response') + ->disableOriginalConstructor() + ->getMock(); + + $loggerMock = $this->getMockBuilder('FOQ\ElasticaBundle\Logger\ElasticaLogger') + ->disableOriginalConstructor() + ->getMock(); + + $queries = array(array('executionMS' => 10), array('executionMS' => 20)); + + $loggerMock->expects($this->once()) + ->method('getQueries') + ->will($this->returnValue($queries)); + + $elasticaDataCollector = new ElasticaDataCollector($loggerMock); + $elasticaDataCollector->collect($requestMock, $responseMock); + $this->assertEquals(30, $elasticaDataCollector->getTime()); + } + } diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php index aa649e2..e65d59d 100644 --- a/Transformer/ModelToElasticaAutoTransformer.php +++ b/Transformer/ModelToElasticaAutoTransformer.php @@ -73,17 +73,26 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf * @param array $objects the object to convert * @param array $fields the keys we want to have in the returned array * @param Elastica_Document $parent the parent document + * * @return array */ protected function transformNested($objects, array $fields, $parent) { - $documents = array(); - foreach($objects as $object) { - $document = $this->transform($object, $fields); - $documents[] = $document->getData(); + if (is_array($objects) || $objects instanceof \Traversable || $objects instanceof \ArrayAccess) { + $documents = array(); + foreach ($objects as $object) { + $document = $this->transform($object, $fields); + $documents[] = $document->getData(); + } + + return $documents; + } elseif (null !== $objects) { + $document = $this->transform($objects, $fields); + + return $document->getData(); } - return $documents; + return array(); } /** diff --git a/composer.json b/composer.json index ad0b1fe..77106c9 100644 --- a/composer.json +++ b/composer.json @@ -18,12 +18,12 @@ "ruflin/elastica": "0.19.8" }, "require-dev":{ - "doctrine/orm":"2.2.*", + "doctrine/orm":">=2.2,<2.5-dev", "doctrine/mongodb-odm":"dev-master", "propel/propel1":"1.6.*" }, "suggest": { - "doctrine/orm": "2.2.*", + "doctrine/orm": ">=2.2,<2.5-dev", "doctrine/mongodb-odm": ">=3.0.0-beta2,<3.1-dev", "propel/propel1": "1.6.*" },