Skip to content

Commit

Permalink
introduce hashmap annotation (#747)
Browse files Browse the repository at this point in the history
  • Loading branch information
saimaz committed Feb 6, 2017
1 parent e780946 commit 9767f69
Show file tree
Hide file tree
Showing 11 changed files with 317 additions and 17 deletions.
69 changes: 69 additions & 0 deletions Annotation/HashMap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

/*
* This file is part of the ONGR package.
*
* (c) NFQ Technologies UAB <info@nfq.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace ONGR\ElasticsearchBundle\Annotation;

/**
* Annotation for property which points to inner object.
*
* @Annotation
* @Target("PROPERTY")
*/
final class HashMap
{
const NAME = 'hash_map';

/**
* Name of the type field. Defaults to normalized property name.
*
* @var string
*/
public $name;

/**
* Property type for nested structure values.
*
* @var mixed
* @Enum({
* "text", "keyword",
* "long", "integer", "short", "byte", "double", "float",
* "date",
* "boolean",
* "binary",
* "geo_point", "geo_shape",
* "ip", "completion", "token_count", "murmur3", "attachments", "percolator"
* })
*/
public $type;

/**
* In this field you can define options.
*
* @var array
*/
public $options = [];

/**
* {@inheritdoc}
*/
public function dump(array $exclude = [])
{
return array_diff_key(
array_merge(
[
'type' => $this->type
],
$this->options
),
$exclude
);
}
}
4 changes: 3 additions & 1 deletion Annotation/Id.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
*/
final class Id implements MetaField
{
const NAME = '_id';

/**
* {@inheritdoc}
*/
public function getName()
{
return '_id';
return self::NAME;
}

/**
Expand Down
19 changes: 19 additions & 0 deletions Annotation/Nested.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,23 @@
*/
final class Nested
{
const NAME = 'nested';

/**
* In this field you can define options.
*
* @var array
*/
public $options = [];

/**
* {@inheritdoc}
*/
public function dump(array $exclude = [])
{
return array_diff_key(
$this->options,
$exclude
);
}
}
19 changes: 19 additions & 0 deletions Annotation/Object.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,23 @@
*/
final class Object
{
const NAME = 'object';

/**
* In this field you can define options.
*
* @var array
*/
public $options = [];

/**
* {@inheritdoc}
*/
public function dump(array $exclude = [])
{
return array_diff_key(
$this->options,
$exclude
);
}
}
4 changes: 3 additions & 1 deletion Annotation/ParentDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
*/
final class ParentDocument implements MetaField
{
const NAME = '_parent';

/**
* Parent document class name.
*
Expand All @@ -33,7 +35,7 @@ final class ParentDocument implements MetaField
*/
public function getName()
{
return '_parent';
return self::NAME;
}

/**
Expand Down
4 changes: 3 additions & 1 deletion Annotation/Routing.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
*/
final class Routing implements MetaField
{
const NAME = '_routing';

/**
* @var bool
*/
Expand All @@ -29,7 +31,7 @@ final class Routing implements MetaField
*/
public function getName()
{
return '_routing';
return self::NAME;
}

/**
Expand Down
4 changes: 3 additions & 1 deletion Annotation/Version.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
*/
final class Version implements MetaField
{
const NAME = '_version';

/**
* {@inheritdoc}
*/
public function getName()
{
return '_version';
return self::NAME;
}

/**
Expand Down
53 changes: 43 additions & 10 deletions Mapping/DocumentParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
use Doctrine\Common\Annotations\Reader;
use ONGR\ElasticsearchBundle\Annotation\Document;
use ONGR\ElasticsearchBundle\Annotation\Embedded;
use ONGR\ElasticsearchBundle\Annotation\HashMap;
use ONGR\ElasticsearchBundle\Annotation\MetaField;
use ONGR\ElasticsearchBundle\Annotation\Nested;
use ONGR\ElasticsearchBundle\Annotation\ParentDocument;
use ONGR\ElasticsearchBundle\Annotation\Property;
use ONGR\ElasticsearchBundle\Exception\MissingDocumentAnnotationException;
Expand All @@ -36,6 +38,7 @@ class DocumentParser
const PARENT_ANNOTATION = 'ONGR\ElasticsearchBundle\Annotation\ParentDocument';
const ROUTING_ANNOTATION = 'ONGR\ElasticsearchBundle\Annotation\Routing';
const VERSION_ANNOTATION = 'ONGR\ElasticsearchBundle\Annotation\Version';
const HASH_MAP_ANNOTATION = 'ONGR\ElasticsearchBundle\Annotation\HashMap';

/**
* @var Reader Used to read document annotations.
Expand All @@ -62,13 +65,6 @@ class DocumentParser
*/
private $properties = [];

/**
* Analyzers used in documents.
*
* @var string[]
*/
private $analyzers = [];

/**
* @param Reader $reader Used for reading annotations.
* @param DocumentFinder $finder Used for resolving namespaces.
Expand Down Expand Up @@ -126,7 +122,7 @@ public function parse(\ReflectionClass $class)
*
* @param \ReflectionClass $document
*
* @return Document|null
* @return Document|object|null
*/
private function getDocumentAnnotationData($document)
{
Expand All @@ -138,7 +134,7 @@ private function getDocumentAnnotationData($document)
*
* @param \ReflectionProperty $property
*
* @return Property|null
* @return Property|object|null
*/
private function getPropertyAnnotationData(\ReflectionProperty $property)
{
Expand All @@ -156,7 +152,7 @@ private function getPropertyAnnotationData(\ReflectionProperty $property)
*
* @param \ReflectionProperty $property
*
* @return Embedded|null
* @return Embedded|object|null
*/
private function getEmbeddedAnnotationData(\ReflectionProperty $property)
{
Expand All @@ -169,6 +165,24 @@ private function getEmbeddedAnnotationData(\ReflectionProperty $property)
return $result;
}

/**
* Returns HashMap annotation data from reader.
*
* @param \ReflectionProperty $property
*
* @return HashMap|object|null
*/
private function getHashMapAnnotationData(\ReflectionProperty $property)
{
$result = $this->reader->getPropertyAnnotation($property, self::HASH_MAP_ANNOTATION);

if ($result !== null && $result->name === null) {
$result->name = Caser::snake($property->getName());
}

return $result;
}

/**
* Returns meta field annotation data from reader.
*
Expand Down Expand Up @@ -237,6 +251,8 @@ private function getAliases(\ReflectionClass $reflectionClass, array &$metaField
foreach ($properties as $name => $property) {
$type = $this->getPropertyAnnotationData($property);
$type = $type !== null ? $type : $this->getEmbeddedAnnotationData($property);
$type = $type !== null ? $type : $this->getHashMapAnnotationData($property);

if ($type === null && $metaFields !== null
&& ($metaData = $this->getMetaFieldAnnotationData($property)) !== null) {
$metaFields[$metaData['name']] = $metaData['settings'];
Expand All @@ -252,6 +268,13 @@ private function getAliases(\ReflectionClass $reflectionClass, array &$metaField
$alias[$type->name]['type'] = $type->type;
}

if ($type instanceof HashMap) {
$alias[$type->name]['type'] = HashMap::NAME;
$alias[$type->name]['aliases'] = [];
}

$alias[$type->name][HashMap::NAME] = $type instanceof HashMap;

switch (true) {
case $property->isPublic():
$propertyType = 'public';
Expand Down Expand Up @@ -364,6 +387,7 @@ private function registerAnnotations()
'ParentDocument',
'Routing',
'Version',
'HashMap',
];

foreach ($annotations as $annotation) {
Expand Down Expand Up @@ -480,6 +504,7 @@ private function getProperties(\ReflectionClass $reflectionClass, $properties =
foreach ($this->getDocumentPropertiesReflection($reflectionClass) as $name => $property) {
$type = $this->getPropertyAnnotationData($property);
$type = $type !== null ? $type : $this->getEmbeddedAnnotationData($property);
$type = $type !== null ? $type : $this->getHashMapAnnotationData($property);

if ((in_array($name, $properties) && !$flag)
|| (!in_array($name, $properties) && $flag)
Expand All @@ -495,6 +520,14 @@ private function getProperties(\ReflectionClass $reflectionClass, $properties =
$map = array_replace_recursive($map, $this->getObjectMapping($type->class));
}

// HashMap object
if ($type instanceof HashMap) {
$map = array_replace_recursive($map, [
'type' => Nested::NAME,
'dynamic' => true,
]);
}

// If there is set some Raw options, it will override current ones.
if (isset($map['options'])) {
$options = $map['options'];
Expand Down
7 changes: 5 additions & 2 deletions Result/Converter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

namespace ONGR\ElasticsearchBundle\Result;

use ONGR\ElasticsearchBundle\Annotation\HashMap;
use ONGR\ElasticsearchBundle\Annotation\Nested;
use ONGR\ElasticsearchBundle\Annotation\Object;
use ONGR\ElasticsearchBundle\Collection\Collection;
use ONGR\ElasticsearchBundle\Mapping\MetadataCollector;
use ONGR\ElasticsearchBundle\Service\Manager;
Expand Down Expand Up @@ -99,8 +102,8 @@ public function assignArrayToObject(array $array, $object, array $aliases)
$value = new \DateTime();
$value->setTimestamp($time);
break;
case 'object':
case 'nested':
case Object::NAME:
case Nested::NAME:
if ($aliases[$name]['multiple']) {
$value = new ObjectIterator($this, $value, $aliases[$name]);
} else {
Expand Down
Loading

0 comments on commit 9767f69

Please sign in to comment.