Merge pull request #794 from merk/property-paths
Added capability to define property paths
This commit is contained in:
commit
07995d9b75
|
@ -25,3 +25,9 @@ https://github.com/FriendsOfSymfony/FOSElasticaBundle/compare/v3.0.4...v3.1.0
|
||||||
ProgressBar helper instead of outputting strings. You can use verbosity
|
ProgressBar helper instead of outputting strings. You can use verbosity
|
||||||
controls on the command to output additional information like memory
|
controls on the command to output additional information like memory
|
||||||
usage, runtime and estimated time.
|
usage, runtime and estimated time.
|
||||||
|
* Added new option `property_path` to a type property definition to allow
|
||||||
|
customisation of the property path used to retrieve data from objects.
|
||||||
|
Setting `property_path` to `false` will configure the Transformer to ignore
|
||||||
|
that property while transforming. Combined with the above POST_TRANSFORM event
|
||||||
|
developers can now create calculated dynamic properties on Elastica documents
|
||||||
|
for indexing. #794
|
||||||
|
|
|
@ -110,6 +110,8 @@ class MappingBuilder
|
||||||
private function fixProperties(&$properties)
|
private function fixProperties(&$properties)
|
||||||
{
|
{
|
||||||
foreach ($properties as $name => &$property) {
|
foreach ($properties as $name => &$property) {
|
||||||
|
unset($property['property_path']);
|
||||||
|
|
||||||
if (!isset($property['type'])) {
|
if (!isset($property['type'])) {
|
||||||
$property['type'] = 'string';
|
$property['type'] = 'string';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
##### Custom Repositories
|
##### Custom Properties
|
||||||
|
|
||||||
Since FOSElasticaBundle 3.1.0, we now dispatch an event for each transformation of an
|
Since FOSElasticaBundle 3.1.0, we now dispatch an event for each transformation of an
|
||||||
object into an Elastica document which allows you to set custom properties on the Elastica
|
object into an Elastica document which allows you to set custom properties on the Elastica
|
||||||
|
|
|
@ -1,6 +1,34 @@
|
||||||
Type configuration
|
Type configuration
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
Custom Property Paths
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Since FOSElasticaBundle 3.1.0, it is now possible to define custom property paths
|
||||||
|
to be used for data retrieval from the underlying model.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
user:
|
||||||
|
mappings:
|
||||||
|
username:
|
||||||
|
property_path: indexableUsername
|
||||||
|
firstName:
|
||||||
|
property_path: names[first]
|
||||||
|
```
|
||||||
|
|
||||||
|
This feature uses the Symfony PropertyAccessor component and supports all features
|
||||||
|
that the component supports.
|
||||||
|
|
||||||
|
The above example would retrieve an indexed field `username` from the property
|
||||||
|
`User->indexableUsername`, and the indexed field `firstName` would be populated from a
|
||||||
|
key `first` from an array on `User->names`.
|
||||||
|
|
||||||
|
Setting the property path to `false` will disable transformation of that value. In this
|
||||||
|
case the mapping will be created but no value will be populated while indexing. You can
|
||||||
|
populate this value by listening to the `POST_TRANSFORM` event emitted by this bundle.
|
||||||
|
See [cookbook/custom-properties.md](cookbook/custom-properties.md) for more information
|
||||||
|
about this event.
|
||||||
|
|
||||||
Handling missing results with FOSElasticaBundle
|
Handling missing results with FOSElasticaBundle
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
|
|
||||||
|
|
54
Tests/Functional/PropertyPathTest.php
Normal file
54
Tests/Functional/PropertyPathTest.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file is part of the FOSElasticaBundle project.
|
||||||
|
*
|
||||||
|
* (c) Tim Nagel <tim@nagel.com.au>
|
||||||
|
*
|
||||||
|
* This source file is subject to the MIT license that is bundled
|
||||||
|
* with this source code in the file LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FOS\ElasticaBundle\Tests\Functional;
|
||||||
|
|
||||||
|
use Elastica\Query\Match;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group functional
|
||||||
|
*/
|
||||||
|
class PropertyPathTest extends WebTestCase
|
||||||
|
{
|
||||||
|
public function testContainerSource()
|
||||||
|
{
|
||||||
|
$client = $this->createClient(array('test_case' => 'ORM'));
|
||||||
|
/** @var \FOS\ElasticaBundle\Persister\ObjectPersister $persister */
|
||||||
|
$persister = $client->getContainer()->get('fos_elastica.object_persister.index.property_paths_type');
|
||||||
|
$obj = new TypeObj();
|
||||||
|
$obj->coll = 'Hello';
|
||||||
|
$persister->insertOne($obj);
|
||||||
|
|
||||||
|
/** @var \Elastica\Index $elClient */
|
||||||
|
$index = $client->getContainer()->get('fos_elastica.index.index');
|
||||||
|
$index->flush(true);
|
||||||
|
|
||||||
|
$query = new Match();
|
||||||
|
$query->setField('something', 'Hello');
|
||||||
|
$search = $index->createSearch($query);
|
||||||
|
|
||||||
|
$this->assertEquals(1, $search->count());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->deleteTmpDir('Basic');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown()
|
||||||
|
{
|
||||||
|
parent::tearDown();
|
||||||
|
|
||||||
|
$this->deleteTmpDir('Basic');
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,8 +13,10 @@ namespace FOS\ElasticaBundle\Tests\Functional;
|
||||||
|
|
||||||
class TypeObj
|
class TypeObj
|
||||||
{
|
{
|
||||||
|
public $id = 5;
|
||||||
public $coll;
|
public $coll;
|
||||||
public $field1;
|
public $field1;
|
||||||
|
public $field2;
|
||||||
|
|
||||||
public function isIndexable()
|
public function isIndexable()
|
||||||
{
|
{
|
||||||
|
|
|
@ -65,6 +65,18 @@ fos_elastica:
|
||||||
provider: ~
|
provider: ~
|
||||||
listener:
|
listener:
|
||||||
is_indexable_callback: [ 'FOS\ElasticaBundle\Tests\Functional\app\ORM\IndexableService', 'isntIndexable' ]
|
is_indexable_callback: [ 'FOS\ElasticaBundle\Tests\Functional\app\ORM\IndexableService', 'isntIndexable' ]
|
||||||
|
property_paths_type:
|
||||||
|
persistence:
|
||||||
|
driver: orm
|
||||||
|
model: FOS\ElasticaBundle\Tests\Functional\TypeObj
|
||||||
|
provider: ~
|
||||||
|
properties:
|
||||||
|
field1:
|
||||||
|
property_path: field2
|
||||||
|
something:
|
||||||
|
property_path: coll
|
||||||
|
dynamic:
|
||||||
|
property_path: false
|
||||||
second_index:
|
second_index:
|
||||||
index_name: foselastica_orm_test_second_%kernel.environment%
|
index_name: foselastica_orm_test_second_%kernel.environment%
|
||||||
types:
|
types:
|
||||||
|
|
|
@ -148,6 +148,20 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
|
||||||
$transformer->transform(new POPO(), array());
|
$transformer->transform(new POPO(), array());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testPropertyPath()
|
||||||
|
{
|
||||||
|
$transformer = $this->getTransformer();
|
||||||
|
|
||||||
|
$document = $transformer->transform(new POPO(), array('name' => array('property_path' => false)));
|
||||||
|
$this->assertInstanceOf('Elastica\Document', $document);
|
||||||
|
$this->assertFalse($document->has('name'));
|
||||||
|
|
||||||
|
$document = $transformer->transform(new POPO(), array('realName' => array('property_path' => 'name')));
|
||||||
|
$this->assertInstanceOf('Elastica\Document', $document);
|
||||||
|
$this->assertTrue($document->has('realName'));
|
||||||
|
$this->assertEquals('someName', $document->get('realName'));
|
||||||
|
}
|
||||||
|
|
||||||
public function testThatCanTransformObject()
|
public function testThatCanTransformObject()
|
||||||
{
|
{
|
||||||
$transformer = $this->getTransformer();
|
$transformer = $this->getTransformer();
|
||||||
|
@ -266,7 +280,7 @@ class ModelToElasticaAutoTransformerTest extends \PHPUnit_Framework_TestCase
|
||||||
$document = $transformer->transform(new POPO(), array(
|
$document = $transformer->transform(new POPO(), array(
|
||||||
'sub' => array(
|
'sub' => array(
|
||||||
'type' => 'nested',
|
'type' => 'nested',
|
||||||
'properties' => array('foo' => '~')
|
'properties' => array('foo' => array())
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
$data = $document->getData();
|
$data = $document->getData();
|
||||||
|
|
|
@ -75,16 +75,24 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
|
||||||
$property = (null !== $mapping['property'])?$mapping['property']:$mapping['type'];
|
$property = (null !== $mapping['property'])?$mapping['property']:$mapping['type'];
|
||||||
$value = $this->propertyAccessor->getValue($object, $property);
|
$value = $this->propertyAccessor->getValue($object, $property);
|
||||||
$document->setParent($this->propertyAccessor->getValue($value, $mapping['identifier']));
|
$document->setParent($this->propertyAccessor->getValue($value, $mapping['identifier']));
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$value = $this->propertyAccessor->getValue($object, $key);
|
$path = isset($mapping['property_path']) ?
|
||||||
|
$mapping['property_path'] :
|
||||||
|
$key;
|
||||||
|
if (false === $path) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$value = $this->propertyAccessor->getValue($object, $path);
|
||||||
|
|
||||||
if (isset($mapping['type']) && in_array($mapping['type'], array('nested', 'object')) && isset($mapping['properties']) && !empty($mapping['properties'])) {
|
if (isset($mapping['type']) && in_array($mapping['type'], array('nested', 'object')) && isset($mapping['properties']) && !empty($mapping['properties'])) {
|
||||||
/* $value is a nested document or object. Transform $value into
|
/* $value is a nested document or object. Transform $value into
|
||||||
* an array of documents, respective the mapped properties.
|
* an array of documents, respective the mapped properties.
|
||||||
*/
|
*/
|
||||||
$document->set($key, $this->transformNested($value, $mapping['properties']));
|
$document->set($key, $this->transformNested($value, $mapping['properties']));
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +103,7 @@ class ModelToElasticaAutoTransformer implements ModelToElasticaTransformerInterf
|
||||||
} else {
|
} else {
|
||||||
$document->addFileContent($key, $value);
|
$document->addFileContent($key, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue