Skip to content

Commit 9767f69

Browse files
authored
introduce hashmap annotation (#747)
1 parent e780946 commit 9767f69

File tree

11 files changed

+317
-17
lines changed

11 files changed

+317
-17
lines changed

Annotation/HashMap.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the ONGR package.
5+
*
6+
* (c) NFQ Technologies UAB <info@nfq.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace ONGR\ElasticsearchBundle\Annotation;
13+
14+
/**
15+
* Annotation for property which points to inner object.
16+
*
17+
* @Annotation
18+
* @Target("PROPERTY")
19+
*/
20+
final class HashMap
21+
{
22+
const NAME = 'hash_map';
23+
24+
/**
25+
* Name of the type field. Defaults to normalized property name.
26+
*
27+
* @var string
28+
*/
29+
public $name;
30+
31+
/**
32+
* Property type for nested structure values.
33+
*
34+
* @var mixed
35+
* @Enum({
36+
* "text", "keyword",
37+
* "long", "integer", "short", "byte", "double", "float",
38+
* "date",
39+
* "boolean",
40+
* "binary",
41+
* "geo_point", "geo_shape",
42+
* "ip", "completion", "token_count", "murmur3", "attachments", "percolator"
43+
* })
44+
*/
45+
public $type;
46+
47+
/**
48+
* In this field you can define options.
49+
*
50+
* @var array
51+
*/
52+
public $options = [];
53+
54+
/**
55+
* {@inheritdoc}
56+
*/
57+
public function dump(array $exclude = [])
58+
{
59+
return array_diff_key(
60+
array_merge(
61+
[
62+
'type' => $this->type
63+
],
64+
$this->options
65+
),
66+
$exclude
67+
);
68+
}
69+
}

Annotation/Id.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
*/
2020
final class Id implements MetaField
2121
{
22+
const NAME = '_id';
23+
2224
/**
2325
* {@inheritdoc}
2426
*/
2527
public function getName()
2628
{
27-
return '_id';
29+
return self::NAME;
2830
}
2931

3032
/**

Annotation/Nested.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,23 @@
1919
*/
2020
final class Nested
2121
{
22+
const NAME = 'nested';
23+
24+
/**
25+
* In this field you can define options.
26+
*
27+
* @var array
28+
*/
29+
public $options = [];
30+
31+
/**
32+
* {@inheritdoc}
33+
*/
34+
public function dump(array $exclude = [])
35+
{
36+
return array_diff_key(
37+
$this->options,
38+
$exclude
39+
);
40+
}
2241
}

Annotation/Object.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,23 @@
2222
*/
2323
final class Object
2424
{
25+
const NAME = 'object';
26+
27+
/**
28+
* In this field you can define options.
29+
*
30+
* @var array
31+
*/
32+
public $options = [];
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function dump(array $exclude = [])
38+
{
39+
return array_diff_key(
40+
$this->options,
41+
$exclude
42+
);
43+
}
2544
}

Annotation/ParentDocument.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
*/
2020
final class ParentDocument implements MetaField
2121
{
22+
const NAME = '_parent';
23+
2224
/**
2325
* Parent document class name.
2426
*
@@ -33,7 +35,7 @@ final class ParentDocument implements MetaField
3335
*/
3436
public function getName()
3537
{
36-
return '_parent';
38+
return self::NAME;
3739
}
3840

3941
/**

Annotation/Routing.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
*/
2020
final class Routing implements MetaField
2121
{
22+
const NAME = '_routing';
23+
2224
/**
2325
* @var bool
2426
*/
@@ -29,7 +31,7 @@ final class Routing implements MetaField
2931
*/
3032
public function getName()
3133
{
32-
return '_routing';
34+
return self::NAME;
3335
}
3436

3537
/**

Annotation/Version.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
*/
2020
final class Version implements MetaField
2121
{
22+
const NAME = '_version';
23+
2224
/**
2325
* {@inheritdoc}
2426
*/
2527
public function getName()
2628
{
27-
return '_version';
29+
return self::NAME;
2830
}
2931

3032
/**

Mapping/DocumentParser.php

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
use Doctrine\Common\Annotations\Reader;
1616
use ONGR\ElasticsearchBundle\Annotation\Document;
1717
use ONGR\ElasticsearchBundle\Annotation\Embedded;
18+
use ONGR\ElasticsearchBundle\Annotation\HashMap;
1819
use ONGR\ElasticsearchBundle\Annotation\MetaField;
20+
use ONGR\ElasticsearchBundle\Annotation\Nested;
1921
use ONGR\ElasticsearchBundle\Annotation\ParentDocument;
2022
use ONGR\ElasticsearchBundle\Annotation\Property;
2123
use ONGR\ElasticsearchBundle\Exception\MissingDocumentAnnotationException;
@@ -36,6 +38,7 @@ class DocumentParser
3638
const PARENT_ANNOTATION = 'ONGR\ElasticsearchBundle\Annotation\ParentDocument';
3739
const ROUTING_ANNOTATION = 'ONGR\ElasticsearchBundle\Annotation\Routing';
3840
const VERSION_ANNOTATION = 'ONGR\ElasticsearchBundle\Annotation\Version';
41+
const HASH_MAP_ANNOTATION = 'ONGR\ElasticsearchBundle\Annotation\HashMap';
3942

4043
/**
4144
* @var Reader Used to read document annotations.
@@ -62,13 +65,6 @@ class DocumentParser
6265
*/
6366
private $properties = [];
6467

65-
/**
66-
* Analyzers used in documents.
67-
*
68-
* @var string[]
69-
*/
70-
private $analyzers = [];
71-
7268
/**
7369
* @param Reader $reader Used for reading annotations.
7470
* @param DocumentFinder $finder Used for resolving namespaces.
@@ -126,7 +122,7 @@ public function parse(\ReflectionClass $class)
126122
*
127123
* @param \ReflectionClass $document
128124
*
129-
* @return Document|null
125+
* @return Document|object|null
130126
*/
131127
private function getDocumentAnnotationData($document)
132128
{
@@ -138,7 +134,7 @@ private function getDocumentAnnotationData($document)
138134
*
139135
* @param \ReflectionProperty $property
140136
*
141-
* @return Property|null
137+
* @return Property|object|null
142138
*/
143139
private function getPropertyAnnotationData(\ReflectionProperty $property)
144140
{
@@ -156,7 +152,7 @@ private function getPropertyAnnotationData(\ReflectionProperty $property)
156152
*
157153
* @param \ReflectionProperty $property
158154
*
159-
* @return Embedded|null
155+
* @return Embedded|object|null
160156
*/
161157
private function getEmbeddedAnnotationData(\ReflectionProperty $property)
162158
{
@@ -169,6 +165,24 @@ private function getEmbeddedAnnotationData(\ReflectionProperty $property)
169165
return $result;
170166
}
171167

168+
/**
169+
* Returns HashMap annotation data from reader.
170+
*
171+
* @param \ReflectionProperty $property
172+
*
173+
* @return HashMap|object|null
174+
*/
175+
private function getHashMapAnnotationData(\ReflectionProperty $property)
176+
{
177+
$result = $this->reader->getPropertyAnnotation($property, self::HASH_MAP_ANNOTATION);
178+
179+
if ($result !== null && $result->name === null) {
180+
$result->name = Caser::snake($property->getName());
181+
}
182+
183+
return $result;
184+
}
185+
172186
/**
173187
* Returns meta field annotation data from reader.
174188
*
@@ -237,6 +251,8 @@ private function getAliases(\ReflectionClass $reflectionClass, array &$metaField
237251
foreach ($properties as $name => $property) {
238252
$type = $this->getPropertyAnnotationData($property);
239253
$type = $type !== null ? $type : $this->getEmbeddedAnnotationData($property);
254+
$type = $type !== null ? $type : $this->getHashMapAnnotationData($property);
255+
240256
if ($type === null && $metaFields !== null
241257
&& ($metaData = $this->getMetaFieldAnnotationData($property)) !== null) {
242258
$metaFields[$metaData['name']] = $metaData['settings'];
@@ -252,6 +268,13 @@ private function getAliases(\ReflectionClass $reflectionClass, array &$metaField
252268
$alias[$type->name]['type'] = $type->type;
253269
}
254270

271+
if ($type instanceof HashMap) {
272+
$alias[$type->name]['type'] = HashMap::NAME;
273+
$alias[$type->name]['aliases'] = [];
274+
}
275+
276+
$alias[$type->name][HashMap::NAME] = $type instanceof HashMap;
277+
255278
switch (true) {
256279
case $property->isPublic():
257280
$propertyType = 'public';
@@ -364,6 +387,7 @@ private function registerAnnotations()
364387
'ParentDocument',
365388
'Routing',
366389
'Version',
390+
'HashMap',
367391
];
368392

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

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

523+
// HashMap object
524+
if ($type instanceof HashMap) {
525+
$map = array_replace_recursive($map, [
526+
'type' => Nested::NAME,
527+
'dynamic' => true,
528+
]);
529+
}
530+
498531
// If there is set some Raw options, it will override current ones.
499532
if (isset($map['options'])) {
500533
$options = $map['options'];

Result/Converter.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111

1212
namespace ONGR\ElasticsearchBundle\Result;
1313

14+
use ONGR\ElasticsearchBundle\Annotation\HashMap;
15+
use ONGR\ElasticsearchBundle\Annotation\Nested;
16+
use ONGR\ElasticsearchBundle\Annotation\Object;
1417
use ONGR\ElasticsearchBundle\Collection\Collection;
1518
use ONGR\ElasticsearchBundle\Mapping\MetadataCollector;
1619
use ONGR\ElasticsearchBundle\Service\Manager;
@@ -99,8 +102,8 @@ public function assignArrayToObject(array $array, $object, array $aliases)
99102
$value = new \DateTime();
100103
$value->setTimestamp($time);
101104
break;
102-
case 'object':
103-
case 'nested':
105+
case Object::NAME:
106+
case Nested::NAME:
104107
if ($aliases[$name]['multiple']) {
105108
$value = new ObjectIterator($this, $value, $aliases[$name]);
106109
} else {

0 commit comments

Comments
 (0)