Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge remote-tracking branch 'cup-of-giraf/nested'

Conflicts:
	DependencyInjection/Configuration.php
  • Loading branch information...
commit 62b28a813e78c8fa4409b069e52350bf23409fe6 2 parents 9b2dc40 + 79eb062
@richardmiller richardmiller authored
View
7 DependencyInjection/Configuration.php
@@ -267,6 +267,13 @@ protected function getMappingsNode()
->end()
->end()
->end()
+ ->arrayNode('_parent')
+ ->treatNullLike(array())
+ ->children()
+ ->scalarNode('type')->end()
+ ->scalarNode('identifier')->defaultValue('id')->end()
+ ->end()
+ ->end()
->arrayNode('properties')
->useAttributeAsKey('name')
->prototype('array')
View
1  Doctrine/AbstractProvider.php
@@ -40,7 +40,6 @@ public function populate(\Closure $loggerClosure = null)
if ($loggerClosure) {
$stepStartTime = microtime(true);
}
-
$objects = $this->fetchSlice($queryBuilder, $this->options['batch_size'], $offset);
$this->objectPersister->insertMany($objects);
View
35 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
View
22 Resetter.php
@@ -58,7 +58,27 @@ public function resetIndexType($indexName, $typeName)
$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;
}
/**
View
36 Tests/ResetterTest.php
@@ -29,6 +29,17 @@ public function setUp()
),
),
),
+ '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 @@ public function testResetIndexType()
$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 @@ public function testResetIndexTypeShouldThrowExceptionForInvalidType()
$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
*/
View
75 Tests/Transformer/ModelToElasticaAutoTransformerTest.php
@@ -92,6 +92,19 @@ public function getFileContents()
{
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 @@ public function testFileContentsAddedForAttachmentMapping()
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());
+ }
}
View
31 Transformer/ModelToElasticaAutoTransformer.php
@@ -45,7 +45,17 @@ public function transform($object, array $fields)
$document = new \Elastica_Document($identifier);
foreach ($fields as $key => $mapping) {
$property = new PropertyPath($key);
- if (isset($mapping['type']) && $mapping['type'] == 'attachment') {
+ if (!empty($mapping['_parent']) && $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));
+ } 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());
@@ -60,6 +70,25 @@ public function transform($object, array $fields)
}
/**
+ * 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
+ * @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();
+ }
+
+ return $documents;
+ }
+
+ /**
* Attempts to convert any type to a string or an array of strings
*
* @param mixed $value
Please sign in to comment.
Something went wrong with that request. Please try again.