From 70c629f857820b0791281352dbdfc5f2055de339 Mon Sep 17 00:00:00 2001 From: predakanga Date: Thu, 9 Aug 2012 13:49:04 +1000 Subject: [PATCH 01/21] Added configuration options to support index-time document boosting --- DependencyInjection/Configuration.php | 19 +++++++++++++++++++ DependencyInjection/FOQElasticaExtension.php | 3 +++ 2 files changed, 22 insertions(+) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index ebd006c..3f17fcb 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -214,6 +214,7 @@ class Configuration ->end() ->append($this->getMappingsNode()) ->append($this->getSourceNode()) + ->append($this->getBoostNode()) ->end() ; @@ -295,4 +296,22 @@ class Configuration return $node; } + + /** + * Returns the array node used for "_boost". + */ + protected function getBoostNode() + { + $builder = new TreeBuilder(); + $node = $builder->root('_boost'); + + $node + ->children() + ->scalarNode('name')->end() + ->scalarNode('null_value')->end() + ->end() + ; + + return $node; + } } diff --git a/DependencyInjection/FOQElasticaExtension.php b/DependencyInjection/FOQElasticaExtension.php index 12658ba..203a12a 100644 --- a/DependencyInjection/FOQElasticaExtension.php +++ b/DependencyInjection/FOQElasticaExtension.php @@ -170,6 +170,9 @@ class FOQElasticaExtension extends Extension if (isset($type['_source'])) { $this->indexConfigs[$indexName]['config']['mappings'][$name]['_source'] = $type['_source']; } + if (isset($type['_boost'])) { + $this->indexConfigs[$indexName]['config']['mappings'][$name]['_boost'] = $type['_boost']; + } if (isset($type['mappings'])) { $this->indexConfigs[$indexName]['config']['mappings'][$name]['properties'] = $type['mappings']; $typeName = sprintf('%s/%s', $indexName, $name); From dd5c5c321ab3f490fe940886a4371adc94097ed9 Mon Sep 17 00:00:00 2001 From: yoye Date: Fri, 24 Aug 2012 12:17:07 +0300 Subject: [PATCH 02/21] Fix total hits count when adding filters --- Paginator/RawPaginatorAdapter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Paginator/RawPaginatorAdapter.php b/Paginator/RawPaginatorAdapter.php index e2f9fb5..bdd98a7 100644 --- a/Paginator/RawPaginatorAdapter.php +++ b/Paginator/RawPaginatorAdapter.php @@ -65,6 +65,6 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface */ public function getTotalHits() { - return $this->searchable->count($this->query); + $this->searchable->search($this->query)->getTotalHits(); } } From 41b024925b2149dc8183c56cb82804e2f4cd50d3 Mon Sep 17 00:00:00 2001 From: yoye Date: Fri, 24 Aug 2012 12:23:10 +0300 Subject: [PATCH 03/21] Update Paginator/RawPaginatorAdapter.php --- Paginator/RawPaginatorAdapter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Paginator/RawPaginatorAdapter.php b/Paginator/RawPaginatorAdapter.php index bdd98a7..77d0527 100644 --- a/Paginator/RawPaginatorAdapter.php +++ b/Paginator/RawPaginatorAdapter.php @@ -65,6 +65,6 @@ class RawPaginatorAdapter implements PaginatorAdapterInterface */ public function getTotalHits() { - $this->searchable->search($this->query)->getTotalHits(); + return $this->searchable->search($this->query)->getTotalHits(); } } From 23c96510d801b0a213692ba5fec89fc23bbaad8d Mon Sep 17 00:00:00 2001 From: matteosister Date: Wed, 19 Sep 2012 12:48:05 +0200 Subject: [PATCH 04/21] colorized output for the foq:elastica:populate command --- Command/PopulateCommand.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Command/PopulateCommand.php b/Command/PopulateCommand.php index ba6affd..53ee7ee 100755 --- a/Command/PopulateCommand.php +++ b/Command/PopulateCommand.php @@ -91,7 +91,7 @@ class PopulateCommand extends ContainerAwareCommand private function populateIndex(OutputInterface $output, $index, $reset) { if ($reset) { - $output->writeln(sprintf('Resetting: %s', $index)); + $output->writeln(sprintf('Resetting %s', $index)); $this->resetter->resetIndex($index); } @@ -99,13 +99,13 @@ class PopulateCommand extends ContainerAwareCommand foreach ($providers as $type => $provider) { $loggerClosure = function($message) use ($output, $index, $type) { - $output->writeln(sprintf('Populating: %s/%s, %s', $index, $type, $message)); + $output->writeln(sprintf('Populating %s/%s, %s', $index, $type, $message)); }; $provider->populate($loggerClosure); } - $output->writeln(sprintf('Refreshing: %s', $index)); + $output->writeln(sprintf('Refreshing %s', $index)); $this->indexManager->getIndex($index)->refresh(); } From 5f1e1326d54e9b816b1f5d2b11bb2fa4abc752cc Mon Sep 17 00:00:00 2001 From: Richard Miller Date: Mon, 24 Sep 2012 23:15:05 +0100 Subject: [PATCH 05/21] Fixing identifier field not being set in TransformerCollection --- .../AbstractElasticaToModelTransformer.php | 8 +++++ Propel/ElasticaToModelTransformer.php | 8 +++++ Resources/config/config.xml | 1 - ...asticaToModelTransformerCollectionTest.php | 8 +++++ .../ElasticaToModelTransformerCollection.php | 31 +++++++++++++------ .../ElasticaToModelTransformerInterface.php | 7 +++++ 6 files changed, 53 insertions(+), 10 deletions(-) diff --git a/Doctrine/AbstractElasticaToModelTransformer.php b/Doctrine/AbstractElasticaToModelTransformer.php index 019619d..df14d00 100755 --- a/Doctrine/AbstractElasticaToModelTransformer.php +++ b/Doctrine/AbstractElasticaToModelTransformer.php @@ -110,6 +110,14 @@ abstract class AbstractElasticaToModelTransformer implements ElasticaToModelTran return $result; } + /** + * {@inheritdoc} + */ + public function getIdentifierField() + { + return $this->options['identifier']; + } + /** * Fetches objects by theses identifier values * diff --git a/Propel/ElasticaToModelTransformer.php b/Propel/ElasticaToModelTransformer.php index ea3547b..a48a5e3 100644 --- a/Propel/ElasticaToModelTransformer.php +++ b/Propel/ElasticaToModelTransformer.php @@ -99,6 +99,14 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface return $this->objectClass; } + /** + * {@inheritdoc} + */ + public function getIdentifierField() + { + return $this->options['identifier']; + } + /** * Fetch objects for theses identifier values * diff --git a/Resources/config/config.xml b/Resources/config/config.xml index 942ddef..f8f180f 100644 --- a/Resources/config/config.xml +++ b/Resources/config/config.xml @@ -64,7 +64,6 @@ - diff --git a/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php b/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php index e739959..05ddaaa 100644 --- a/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php +++ b/Tests/Transformer/ElasticaToModelTransformerCollectionTest.php @@ -19,11 +19,19 @@ class ElasticaToModelTransformerCollectionTest extends \PHPUnit_Framework_TestCa ->method('getObjectClass') ->will($this->returnValue('FOQ\ElasticaBundle\Tests\Transformer\POPO')); + $transformer1->expects($this->any()) + ->method('getIdentifierField') + ->will($this->returnValue('id')); + $transformer2 = $this->getMock('FOQ\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface'); $transformer2->expects($this->any()) ->method('getObjectClass') ->will($this->returnValue('FOQ\ElasticaBundle\Tests\Transformer\POPO2')); + $transformer2->expects($this->any()) + ->method('getIdentifierField') + ->will($this->returnValue('id')); + $this->collection = new ElasticaToModelTransformerCollection($this->transformers = array( 'type1' => $transformer1, 'type2' => $transformer2, diff --git a/Transformer/ElasticaToModelTransformerCollection.php b/Transformer/ElasticaToModelTransformerCollection.php index 33bd698..a11172b 100644 --- a/Transformer/ElasticaToModelTransformerCollection.php +++ b/Transformer/ElasticaToModelTransformerCollection.php @@ -12,14 +12,10 @@ use FOQ\ElasticaBundle\HybridResult; class ElasticaToModelTransformerCollection implements ElasticaToModelTransformerInterface { protected $transformers = array(); - protected $options = array( - 'identifier' => 'id' - ); - public function __construct(array $transformers, array $options) + public function __construct(array $transformers) { $this->transformers = $transformers; - $this->options = array_merge($this->options, $options); } public function getObjectClass() @@ -29,6 +25,16 @@ class ElasticaToModelTransformerCollection implements ElasticaToModelTransformer }, $this->transformers); } + /** + * {@inheritdoc} + */ + public function getIdentifierField() + { + return array_map(function ($transformer) { + return $transformer->getIdentifierField(); + }, $this->transformers); + } + public function transform(array $elasticaObjects) { $sorted = array(); @@ -36,12 +42,19 @@ class ElasticaToModelTransformerCollection implements ElasticaToModelTransformer $sorted[$object->getType()][] = $object; } - $identifierGetter = 'get' . ucfirst($this->options['identifier']); - $transformed = array(); foreach ($sorted AS $type => $objects) { $transformedObjects = $this->transformers[$type]->transform($objects); - $transformed[$type] = array_combine(array_map(function($o) use ($identifierGetter) {return $o->$identifierGetter();},$transformedObjects),$transformedObjects); + $identifierGetter = 'get' . ucfirst($this->transformers[$type]->getIdentifierField()); + $transformed[$type] = array_combine( + array_map( + function($o) use ($identifierGetter) { + return $o->$identifierGetter(); + }, + $transformedObjects + ), + $transformedObjects + ); } $result = array(); @@ -70,4 +83,4 @@ class ElasticaToModelTransformerCollection implements ElasticaToModelTransformer return $transformer->getObjectClass(); }, $this->transformers); } -} \ No newline at end of file +} diff --git a/Transformer/ElasticaToModelTransformerInterface.php b/Transformer/ElasticaToModelTransformerInterface.php index 5f3f5aa..971bdfe 100644 --- a/Transformer/ElasticaToModelTransformerInterface.php +++ b/Transformer/ElasticaToModelTransformerInterface.php @@ -24,4 +24,11 @@ interface ElasticaToModelTransformerInterface * @return string */ function getObjectClass(); + + /** + * Returns the identifier field from the options + * + * @return string the identifier field + */ + function getIdentifierField(); } From e35134b780ae4abf3571c4a62aba4419f581ed5b Mon Sep 17 00:00:00 2001 From: Konstantin Tjuterev Date: Mon, 1 Oct 2012 15:36:54 +0300 Subject: [PATCH 06/21] Added configuration mapping for properties key, allows configuing mapping for objects/nested documents --- DependencyInjection/Configuration.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 3f17fcb..dc577c0 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -266,6 +266,26 @@ class Configuration ->end() ->end() ->end() + ->arrayNode('properties') + ->useAttributeAsKey('name') + ->prototype('array') + ->treatNullLike(array()) + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('type')->defaultValue('string')->end() + ->scalarNode('boost')->end() + ->scalarNode('store')->end() + ->scalarNode('index')->end() + ->scalarNode('index_analyzer')->end() + ->scalarNode('search_analyzer')->end() + ->scalarNode('analyzer')->end() + ->scalarNode('term_vector')->end() + ->scalarNode('null_value')->end() + ->booleanNode('include_in_all')->defaultValue('true')->end() + ->scalarNode('lat_lon')->end() + ->end() + ->end() + ->end() ->end() ->end() ; From d49c530c5515572cbbf096ade047f8bec2f83990 Mon Sep 17 00:00:00 2001 From: Ad van der Veer Date: Mon, 1 Oct 2012 17:20:52 +0200 Subject: [PATCH 07/21] Updated the DoctrineMongoDB event subscriber tag --- DependencyInjection/FOQElasticaExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DependencyInjection/FOQElasticaExtension.php b/DependencyInjection/FOQElasticaExtension.php index 203a12a..b26c30a 100644 --- a/DependencyInjection/FOQElasticaExtension.php +++ b/DependencyInjection/FOQElasticaExtension.php @@ -320,7 +320,7 @@ class FOQElasticaExtension extends Extension $listenerDef->replaceArgument(2, $this->getDoctrineEvents($typeConfig)); switch ($typeConfig['driver']) { case 'orm': $listenerDef->addTag('doctrine.event_subscriber'); break; - case 'mongodb': $listenerDef->addTag('doctrine.odm.mongodb.event_subscriber'); break; + case 'mongodb': $listenerDef->addTag('doctrine_mongodb.odm.event_subscriber'); break; } if (isset($typeConfig['listener']['is_indexable_callback'])) { $callback = $typeConfig['listener']['is_indexable_callback']; From bb6a3cf08d68f375537a0c9381f01193dd71547f Mon Sep 17 00:00:00 2001 From: Robin van der Vleuten Date: Sun, 30 Sep 2012 19:58:59 +0200 Subject: [PATCH 08/21] Allow providing a URL or host and port for client configurations --- DependencyInjection/Configuration.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 661d893..7348a47 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -46,8 +46,9 @@ class Configuration ->prototype('array') ->performNoDeepMerging() ->children() - ->scalarNode('host')->defaultValue('localhost')->end() - ->scalarNode('port')->defaultValue('9000')->end() + ->scalarNode('url')->end() + ->scalarNode('host')->end() + ->scalarNode('port')->end() ->scalarNode('timeout')->end() ->scalarNode('headers')->end() ->end() From f4c0a4abdae9587721ba9858192bfc57a654a5ef Mon Sep 17 00:00:00 2001 From: Francisco Facioni Date: Mon, 15 Oct 2012 17:18:04 -0300 Subject: [PATCH 09/21] adds to the config the index parameter, needed for disabling the analyzer or the indexing --- DependencyInjection/FOQElasticaExtension.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DependencyInjection/FOQElasticaExtension.php b/DependencyInjection/FOQElasticaExtension.php index b26c30a..92310cc 100644 --- a/DependencyInjection/FOQElasticaExtension.php +++ b/DependencyInjection/FOQElasticaExtension.php @@ -187,6 +187,9 @@ class FOQElasticaExtension extends Extension if (isset($type['search_analyzer'])) { $this->indexConfigs[$indexName]['config']['mappings'][$name]['search_analyzer'] = $type['search_analyzer']; } + if (isset($type['index'])) { + $this->indexConfigs[$indexName]['config']['mappings'][$name]['index'] = $type['index']; + } } } From 58eaf6b03eb244f82a571ebe749c23e5287672ce Mon Sep 17 00:00:00 2001 From: Olivier Dolbeau Date: Mon, 5 Nov 2012 11:00:18 +0100 Subject: [PATCH 10/21] Allow multiple servers in configuration --- DependencyInjection/Configuration.php | 37 ++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 69990ab..cfda3a9 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -45,10 +45,41 @@ class Configuration ->useAttributeAsKey('id') ->prototype('array') ->performNoDeepMerging() + ->beforeNormalization() + ->ifTrue(function($v) { return isset($v['host']) && isset($v['port']); }) + ->then(function($v) { + return array( + 'servers' => array( + 'default' => array( + 'host' => $v['host'], + 'port' => $v['port'], + ) + ) + ); + }) + ->end() + ->beforeNormalization() + ->ifTrue(function($v) { return isset($v['url']); }) + ->then(function($v) { + return array( + 'servers' => array( + 'default' => array( + 'url' => $v['url'], + ) + ) + ); + }) + ->end() ->children() - ->scalarNode('url')->end() - ->scalarNode('host')->end() - ->scalarNode('port')->end() + ->arrayNode('servers') + ->prototype('array') + ->children() + ->scalarNode('url')->end() + ->scalarNode('host')->end() + ->scalarNode('port')->end() + ->end() + ->end() + ->end() ->scalarNode('timeout')->end() ->scalarNode('headers')->end() ->end() From e6bfda8e80b127b6a7463d776f4ec0ea407c4599 Mon Sep 17 00:00:00 2001 From: daFish Date: Sun, 18 Nov 2012 20:30:51 +0100 Subject: [PATCH 11/21] Added support for Symfony 2.2 to composer.json --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 350c4a0..6188271 100644 --- a/composer.json +++ b/composer.json @@ -12,9 +12,9 @@ ], "require": { "php": ">=5.3.2", - "symfony/framework-bundle": "2.1.*", - "symfony/console": "2.1.*", - "symfony/form": "2.1.*", + "symfony/framework-bundle": ">=2.1.0,<2.3-dev", + "symfony/console": ">=2.1.0,<2.3-dev", + "symfony/form": ">=2.1.0,<2.3-dev", "ruflin/elastica": "0.19.3" }, "require-dev":{ From 679480e496023cc3a23690139664d87deccd3cb9 Mon Sep 17 00:00:00 2001 From: Julien Muetton Date: Thu, 22 Nov 2012 14:31:22 +0100 Subject: [PATCH 12/21] add ability to configure nested mapping ``` yaml foq_elastica: clients: default: { host: localhost, port: 9200 } indexes: website: client: default types: product: mappings: name: { type: string } price: { type: float} specifications: type: object properties: name: {type: string} value: {type: string, analyzer: keyword} ``` --- DependencyInjection/Configuration.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 69990ab..5dfdc51 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -267,6 +267,26 @@ class Configuration ->end() ->end() ->end() + ->arrayNode('properties') + ->useAttributeAsKey('name') + ->prototype('array') + ->treatNullLike(array()) + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('type')->defaultValue('string')->end() + ->scalarNode('boost')->end() + ->scalarNode('store')->end() + ->scalarNode('index')->end() + ->scalarNode('index_analyzer')->end() + ->scalarNode('search_analyzer')->end() + ->scalarNode('analyzer')->end() + ->scalarNode('term_vector')->end() + ->scalarNode('null_value')->end() + ->booleanNode('include_in_all')->defaultValue('true')->end() + ->scalarNode('lat_lon')->end() + ->end() + ->end() + ->end() ->end() ->end() ; From 5c8dd9b7a6f4fcc6aa8bfb9e60bbaafe5eada682 Mon Sep 17 00:00:00 2001 From: Julien Muetton Date: Thu, 22 Nov 2012 14:35:01 +0100 Subject: [PATCH 13/21] Transformer transforms nested documents --- .../ModelToElasticaAutoTransformer.php | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php index df72d6f..31f2bb7 100644 --- a/Transformer/ModelToElasticaAutoTransformer.php +++ b/Transformer/ModelToElasticaAutoTransformer.php @@ -45,7 +45,13 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf $document = new \Elastica_Document($identifier); foreach ($fields as $key => $mapping) { $property = new PropertyPath($key); - if (isset($mapping['type']) && $mapping['type'] == 'attachment') { + if (isset($mapping['type']) && in_array($mapping['type'], array('nested', 'object'))) { + $submapping = $mapping['properties']; + $subcollection = $property->getValue($object); + $document->add($key, $this->transformNested($subcollection, $submapping)); + } else if (isset($mapping['type']) && $mapping['type'] == 'multi_field') { + throw new \Exception('Please implement me !'); + } else if (isset($mapping['type']) && $mapping['type'] == 'attachment') { $attachment = $property->getValue($object); if ($attachment instanceof \SplFileInfo) { $document->addFile($key, $attachment->getPathName()); @@ -59,6 +65,23 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf return $document; } + /** + * transform a nested document or an object property into an array of ElasticaDocument + * + * @param array $objects the object to convert + * @param array $fields the keys we want to have in the returned array + * @return array + */ + protected function transformNested($objects, array $fields) + { + $documents = array(); + foreach($objects as $object) { + $documents[] = $this->transform($object, $fields)->getData(); + } + + return $documents; + } + /** * Attempts to convert any type to a string or an array of strings * From a901304a590e63bda66c78fa8d92c30ef54a5698 Mon Sep 17 00:00:00 2001 From: Julien Muetton Date: Mon, 26 Nov 2012 13:49:59 +0100 Subject: [PATCH 14/21] remove trailing whitespace --- Doctrine/AbstractProvider.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Doctrine/AbstractProvider.php b/Doctrine/AbstractProvider.php index 8f51e57..6a3e008 100644 --- a/Doctrine/AbstractProvider.php +++ b/Doctrine/AbstractProvider.php @@ -40,7 +40,6 @@ abstract class AbstractProvider extends BaseAbstractProvider if ($loggerClosure) { $stepStartTime = microtime(true); } - $objects = $this->fetchSlice($queryBuilder, $this->options['batch_size'], $offset); $this->objectPersister->insertMany($objects); From 23f591bf0190493c6f06ab66480181a13044a895 Mon Sep 17 00:00:00 2001 From: Julien Muetton Date: Mon, 26 Nov 2012 13:50:14 +0100 Subject: [PATCH 15/21] allow _parent mapping --- DependencyInjection/Configuration.php | 7 +++++++ Transformer/ModelToElasticaAutoTransformer.php | 16 +++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 5dfdc51..b4a588a 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -267,6 +267,13 @@ class Configuration ->end() ->end() ->end() + ->arrayNode('_parent') + ->treatNullLike(array()) + ->children() + ->scalarNode('type')->end() + ->scalarNode('identifier')->defaultValue('id')->end() + ->end() + ->end() ->arrayNode('properties') ->useAttributeAsKey('name') ->prototype('array') diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php index 31f2bb7..17cbc30 100644 --- a/Transformer/ModelToElasticaAutoTransformer.php +++ b/Transformer/ModelToElasticaAutoTransformer.php @@ -45,10 +45,14 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf $document = new \Elastica_Document($identifier); foreach ($fields as $key => $mapping) { $property = new PropertyPath($key); - if (isset($mapping['type']) && in_array($mapping['type'], array('nested', 'object'))) { - $submapping = $mapping['properties']; + if (isset($mapping['_parent'])) { + $parent = $property->getValue($object); + $identifierProperty = new PropertyPath($mapping['_parent']['identifier']); + $document->setParent($identifierProperty->getValue($parent)); + } else if (isset($mapping['type']) && in_array($mapping['type'], array('nested', 'object'))) { + $submapping = $mapping['properties']; $subcollection = $property->getValue($object); - $document->add($key, $this->transformNested($subcollection, $submapping)); + $document->add($key, $this->transformNested($subcollection, $submapping, $document)); } else if (isset($mapping['type']) && $mapping['type'] == 'multi_field') { throw new \Exception('Please implement me !'); } else if (isset($mapping['type']) && $mapping['type'] == 'attachment') { @@ -70,13 +74,15 @@ 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) + protected function transformNested($objects, array $fields, $parent) { $documents = array(); foreach($objects as $object) { - $documents[] = $this->transform($object, $fields)->getData(); + $document = $this->transform($object, $fields); + $documents[] = $document->getData(); } return $documents; From ea3191033f5b2f5598ec4735b635060a44929cfb Mon Sep 17 00:00:00 2001 From: Julien Muetton Date: Mon, 26 Nov 2012 13:55:48 +0100 Subject: [PATCH 16/21] add documentation for nested, object and _parent --- README.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/README.md b/README.md index f472e5a..774e7ec 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,41 @@ Elasticsearch type is comparable to Doctrine entity repository. Our type is now available as a service: `foq_elastica.index.website.user`. It is an instance of `Elastica_Type`. +### Declaring parent field + + foq_elastica: + clients: + default: { host: localhost, port: 9200 } + indexes: + website: + client: default + types: + comment: + mappings: + post: {_parent: { type: "post", identifier: "id" } } + date: { boost: 5 } + content: ~ + +### Declaring `nested` or `object` + + foq_elastica: + clients: + default: { host: localhost, port: 9200 } + indexes: + website: + client: default + types: + post: + mappings: + date: { boost: 5 } + title: { boost: 3 } + content: ~ + comments: + type: "nested" + properties: + date: { boost: 5 } + content: ~ + ### Populate the types php app/console foq:elastica:populate From a36ec87f40b36ea24e81cb34c6b9573f398d2367 Mon Sep 17 00:00:00 2001 From: Julien Muetton Date: Mon, 26 Nov 2012 14:37:47 +0100 Subject: [PATCH 17/21] Add tests for `_parent`, `nested` and `object` types --- .../ModelToElasticaAutoTransformerTest.php | 75 +++++++++++++++++++ .../ModelToElasticaAutoTransformer.php | 2 +- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php index 7f2595c..6f2aaea 100644 --- a/Tests/Transformer/ModelToElasticaAutoTransformerTest.php +++ b/Tests/Transformer/ModelToElasticaAutoTransformerTest.php @@ -92,6 +92,19 @@ class POPO { return $this->file; } + + public function getSub() + { + return array( + (object) array('foo' => 'foo', 'bar' => 'foo', 'id' => 1), + (object) array('foo' => 'bar', 'bar' => 'bar', 'id' => 2), + ); + } + + public function getUpper() + { + return (object) array('id' => 'parent', 'name' => 'a random name'); + } } class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase @@ -215,4 +228,66 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase base64_encode(file_get_contents(__DIR__ . '/../fixtures/attachment.odt')), $data['fileContents'] ); } + + public function testNestedMapping() + { + $transformer = new ModelToElasticaAutoTransformer(); + $document = $transformer->transform(new POPO(), array( + 'sub' => array( + 'type' => 'nested', + 'properties' => array('foo' => '~') + ) + )); + $data = $document->getData(); + + $this->assertTrue(array_key_exists('sub', $data)); + $this->assertInternalType('array', $data['sub']); + $this->assertEquals(array( + array('foo' => 'foo'), + array('foo' => 'bar') + ), $data['sub']); + } + + public function tesObjectMapping() + { + $transformer = new ModelToElasticaAutoTransformer(); + $document = $transformer->transform(new POPO(), array( + 'sub' => array( + 'type' => 'object', + 'properties' => array('bar') + ) + )); + $data = $document->getData(); + + $this->assertTrue(array_key_exists('sub', $data)); + $this->assertInternalType('array', $data['sub']); + $this->assertEquals(array( + array('bar' => 'foo'), + array('bar' => 'bar') + ), $data['sub']); + } + + public function testParentMapping() + { + $transformer = new ModelToElasticaAutoTransformer(); + $document = $transformer->transform(new POPO(), array( + 'upper' => array( + '_parent' => array('type' => 'upper', 'identifier' => 'id'), + ) + )); + + $this->assertEquals("parent", $document->getParent()); + } + + public function testParentMappingWithCustomIdentifier() + { + $transformer = new ModelToElasticaAutoTransformer(); + $document = $transformer->transform(new POPO(), array( + 'upper' => array( + '_parent' => array('type' => 'upper', 'identifier' => 'name'), + ) + )); + + $this->assertEquals("a random name", $document->getParent()); + } } diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php index 17cbc30..172d31d 100644 --- a/Transformer/ModelToElasticaAutoTransformer.php +++ b/Transformer/ModelToElasticaAutoTransformer.php @@ -45,7 +45,7 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf $document = new \Elastica_Document($identifier); foreach ($fields as $key => $mapping) { $property = new PropertyPath($key); - if (isset($mapping['_parent'])) { + if (!empty($mapping['_parent'])) { $parent = $property->getValue($object); $identifierProperty = new PropertyPath($mapping['_parent']['identifier']); $document->setParent($identifierProperty->getValue($parent)); From 10eae2f254eb0105d72697346929ba984b1ae0b8 Mon Sep 17 00:00:00 2001 From: Julien Muetton Date: Mon, 26 Nov 2012 16:04:50 +0100 Subject: [PATCH 18/21] fixes php5.3 defines `~` for default empty `_parent` property --- Transformer/ModelToElasticaAutoTransformer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php index 172d31d..cc76e8f 100644 --- a/Transformer/ModelToElasticaAutoTransformer.php +++ b/Transformer/ModelToElasticaAutoTransformer.php @@ -45,7 +45,7 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf $document = new \Elastica_Document($identifier); foreach ($fields as $key => $mapping) { $property = new PropertyPath($key); - if (!empty($mapping['_parent'])) { + if (!empty($mapping['_parent']) && $mapping['_parent'] !== '~') { $parent = $property->getValue($object); $identifierProperty = new PropertyPath($mapping['_parent']['identifier']); $document->setParent($identifierProperty->getValue($parent)); From 79eb062cf75e7e9d540014347c43cc3e10dca6b8 Mon Sep 17 00:00:00 2001 From: Julien Muetton Date: Wed, 28 Nov 2012 12:07:09 +0100 Subject: [PATCH 19/21] add `_parent` in mapping during index reset --- Resetter.php | 22 +++++++++++++++++++++- Tests/ResetterTest.php | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/Resetter.php b/Resetter.php index f8d94ed..2773140 100644 --- a/Resetter.php +++ b/Resetter.php @@ -58,7 +58,27 @@ class Resetter $type = $indexConfig['index']->getType($typeName); $type->delete(); - $type->setMapping($indexConfig['config']['mappings'][$typeName]['properties']); + $mapping = $this->createMapping($indexConfig['config']['mappings'][$typeName]); + $type->setMapping($mapping); + } + + /** + * create type mapping object + * + * @param array $indexConfig + * @return Elastica_Type_Mapping + */ + protected function createMapping($indexConfig) + { + $mapping = \Elastica_Type_Mapping::create($indexConfig['properties']); + + foreach($indexConfig['properties'] as $field => $type) { + if (!empty($type['_parent']) && $type['_parent'] !== '~') { + $mapping->setParam('_parent', array('type' => $type['_parent']['type'])); + } + } + + return $mapping; } /** diff --git a/Tests/ResetterTest.php b/Tests/ResetterTest.php index d59da18..754310c 100644 --- a/Tests/ResetterTest.php +++ b/Tests/ResetterTest.php @@ -29,6 +29,17 @@ class ResetterTest extends \PHPUnit_Framework_TestCase ), ), ), + 'parent' => array( + 'index' => $this->getMockElasticaIndex(), + 'config' => array( + 'mappings' => array( + 'a' => array('properties' => array( + 'field_1' => array('_parent' => array('type' => 'b', 'identifier' => 'id')), + 'field_2' => array())), + 'b' => array('properties' => array()), + ), + ), + ), ); } @@ -80,9 +91,10 @@ class ResetterTest extends \PHPUnit_Framework_TestCase $type->expects($this->once()) ->method('delete'); + $mapping = \Elastica_Type_Mapping::create($this->indexConfigsByName['foo']['config']['mappings']['a']['properties']); $type->expects($this->once()) ->method('setMapping') - ->with($this->indexConfigsByName['foo']['config']['mappings']['a']['properties']); + ->with($mapping); $resetter = new Resetter($this->indexConfigsByName); $resetter->resetIndexType('foo', 'a'); @@ -106,6 +118,28 @@ class ResetterTest extends \PHPUnit_Framework_TestCase $resetter->resetIndexType('foo', 'c'); } + public function testIndexMappingForParent() + { + $type = $this->getMockElasticaType(); + + $this->indexConfigsByName['parent']['index']->expects($this->once()) + ->method('getType') + ->with('a') + ->will($this->returnValue($type)); + + $type->expects($this->once()) + ->method('delete'); + + $mapping = \Elastica_Type_Mapping::create($this->indexConfigsByName['parent']['config']['mappings']['a']['properties']); + $mapping->setParam('_parent', array('type' => 'b')); + $type->expects($this->once()) + ->method('setMapping') + ->with($mapping); + + $resetter = new Resetter($this->indexConfigsByName); + $resetter->resetIndexType('parent', 'a'); + } + /** * @return Elastica_Index */ From e5fef260f22820164b658ad6c732505f7fcd5684 Mon Sep 17 00:00:00 2001 From: daFish Date: Thu, 29 Nov 2012 10:00:51 +0100 Subject: [PATCH 20/21] Changed servers to numeric indexes instead of associative indexes --- DependencyInjection/Configuration.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 1c47d23..6aa179d 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -50,7 +50,7 @@ class Configuration ->then(function($v) { return array( 'servers' => array( - 'default' => array( + array( 'host' => $v['host'], 'port' => $v['port'], ) @@ -63,7 +63,7 @@ class Configuration ->then(function($v) { return array( 'servers' => array( - 'default' => array( + array( 'url' => $v['url'], ) ) From 7717d4d580e676dd65de14206212665129cd7e00 Mon Sep 17 00:00:00 2001 From: craig Date: Thu, 29 Nov 2012 14:32:47 +0000 Subject: [PATCH 21/21] Remove exception when multi_field type is used --- Transformer/ModelToElasticaAutoTransformer.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/Transformer/ModelToElasticaAutoTransformer.php b/Transformer/ModelToElasticaAutoTransformer.php index cc76e8f..aa649e2 100644 --- a/Transformer/ModelToElasticaAutoTransformer.php +++ b/Transformer/ModelToElasticaAutoTransformer.php @@ -53,8 +53,6 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf $submapping = $mapping['properties']; $subcollection = $property->getValue($object); $document->add($key, $this->transformNested($subcollection, $submapping, $document)); - } else if (isset($mapping['type']) && $mapping['type'] == 'multi_field') { - throw new \Exception('Please implement me !'); } else if (isset($mapping['type']) && $mapping['type'] == 'attachment') { $attachment = $property->getValue($object); if ($attachment instanceof \SplFileInfo) {