Skip to content

Commit 9a9b815

Browse files
Christoph Singersaimaz
authored andcommitted
Fix "fields" annotation (#894)
* Fix "fields" annotation * Bugfix: correct handling of `normalizer` in analysis config * Better unit test for DocumentParser tests `fields` mapping and `normalizer` settings
1 parent 1cc5c65 commit 9a9b815

File tree

4 files changed

+155
-7
lines changed

4 files changed

+155
-7
lines changed

Mapping/DocumentParser.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ private function getClassMetadata(\ReflectionClass $class): array
151151

152152
if ($annotation instanceof Property) {
153153
$fieldMapping['type'] = $annotation->type;
154+
if ($annotation->fields) {
155+
$fieldMapping['fields'] = $annotation->fields;
156+
}
154157
$fieldMapping['analyzer'] = $annotation->analyzer;
155158
$fieldMapping['search_analyzer'] = $annotation->searchAnalyzer;
156159
$fieldMapping['search_quote_analyzer'] = $annotation->searchQuoteAnalyzer;
@@ -267,7 +270,14 @@ public function getAnalysisConfig(\ReflectionClass $class): array
267270
}
268271
}
269272

270-
foreach (['tokenizer', 'filter', 'normalizer', 'char_filter'] as $type) {
273+
$normalizers = $this->getListFromArrayByKey('normalizer', $mapping);
274+
foreach ($normalizers as $normalizer) {
275+
if (isset($this->analysisConfig['normalizer'][$normalizer])) {
276+
$config['normalizer'][$normalizer] = $this->analysisConfig['normalizer'][$normalizer];
277+
}
278+
}
279+
280+
foreach (['tokenizer', 'filter', 'char_filter'] as $type) {
271281
$list = $this->getListFromArrayByKey($type, $config);
272282

273283
foreach ($list as $listItem) {

Tests/Unit/Mapping/DocumentParserTest.php

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,19 @@
1313

1414
use Doctrine\Common\Annotations\AnnotationReader;
1515
use Doctrine\Common\Cache\Cache;
16+
use ONGR\App\Document\DummyDocument;
17+
use ONGR\App\Document\TestDocument;
1618
use ONGR\App\Entity\DummyDocumentInTheEntityDirectory;
1719
use ONGR\ElasticsearchBundle\Mapping\DocumentParser;
1820
use PHPUnit\Framework\TestCase;
21+
use Symfony\Component\Yaml\Yaml;
1922

2023
class DocumentParserTest extends TestCase
2124
{
2225
public function testDocumentParsing()
2326
{
2427

2528
$parser = new DocumentParser(new AnnotationReader(), $this->createMock(Cache::class));
26-
;
2729

2830
$indexMetadata = $parser->getIndexMetadata(new \ReflectionClass(DummyDocumentInTheEntityDirectory::class));
2931

@@ -41,4 +43,98 @@ public function testDocumentParsing()
4143

4244
$this->assertEquals($expected, $indexMetadata);
4345
}
46+
47+
public function testParsingWithMultiFieldsMapping()
48+
{
49+
$parser = new DocumentParser(new AnnotationReader(), $this->createMock(Cache::class));
50+
51+
$indexMetadata = $parser->getIndexMetadata(new \ReflectionClass(TestDocument::class));
52+
53+
// Mapping definition for field "title" should be there
54+
$this->assertNotEmpty($indexMetadata['mappings']['_doc']['properties']['title']);
55+
$title_field_def = $indexMetadata['mappings']['_doc']['properties']['title'];
56+
57+
// title should have `fields` sub-array
58+
$this->assertArrayHasKey('fields', $title_field_def);
59+
60+
// `fields` should look like so:
61+
$expected = [
62+
'raw' => ['type' => 'keyword'],
63+
'increment' => ['type' => 'text', 'analyzer' => 'incrementalAnalyzer'],
64+
'sorting' => ['type' => 'keyword', 'normalizer' => 'lowercase_normalizer']
65+
];
66+
67+
$this->assertEquals($expected, $title_field_def['fields']);
68+
}
69+
70+
public function testGetAnalysisConfig()
71+
{
72+
// Global analysis settings used for this test, usually set in the bundle configuration
73+
// sets custom analyzer, filter, and normalizer
74+
$config_analysis = [
75+
'analyzer' => [
76+
'incrementalAnalyzer' => [
77+
'type' => 'custom',
78+
'tokenizer' => 'standard',
79+
'filter' => [
80+
0 => 'lowercase',
81+
1 => 'edge_ngram_filter',
82+
],
83+
],
84+
'unusedAnalyzer' => [
85+
'type' => 'custom',
86+
'tokenizer' => 'standard'
87+
]
88+
],
89+
'filter' => [
90+
'edge_ngram_filter' => [
91+
'type' => 'edge_ngram',
92+
'min_gram' => 1,
93+
'max_gram' => 20,
94+
],
95+
],
96+
'normalizer' => [
97+
'lowercase_normalizer' => [
98+
'type' => 'custom',
99+
'filter' => ['lowercase']
100+
],
101+
'unused_normalizer' => [
102+
'type' => 'custom'
103+
]
104+
]
105+
];
106+
107+
$parser = new DocumentParser(new AnnotationReader(), $this->createMock(Cache::class), $config_analysis);
108+
$analysis = $parser->getAnalysisConfig(new \ReflectionClass(TestDocument::class));
109+
110+
$expected = [
111+
'analyzer' => [
112+
'incrementalAnalyzer' => [
113+
'type' => 'custom',
114+
'tokenizer' => 'standard',
115+
'filter' => [
116+
0 => 'lowercase',
117+
1 => 'edge_ngram_filter',
118+
],
119+
],
120+
],
121+
// 'unusedAnalyzer' must not be there because it is not used
122+
'filter' => [
123+
'edge_ngram_filter' => [
124+
'type' => 'edge_ngram',
125+
'min_gram' => 1,
126+
'max_gram' => 20,
127+
],
128+
],
129+
'normalizer' => [
130+
'lowercase_normalizer' => [
131+
'type' => 'custom',
132+
'filter' => ['lowercase']
133+
]
134+
// 'unused_normalizer' must not be there
135+
]
136+
];
137+
138+
$this->assertEquals($expected, $analysis);
139+
}
44140
}

Tests/app/src/Document/DummyDocument.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,9 @@ class DummyDocument
3939
* @ES\Property(
4040
* type="text",
4141
* name="title",
42-
* settings={
43-
* "fields"={
44-
* "raw"={"type"="keyword"},
45-
* "increment"={"type"="text", "analyzer"="incrementalAnalyzer"}
46-
* }
42+
* fields={
43+
* "raw"={"type"="keyword"},
44+
* "increment"={"type"="text", "analyzer"="incrementalAnalyzer"}
4745
* }
4846
* )
4947
*/
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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\App\Document;
13+
14+
use Doctrine\Common\Collections\ArrayCollection;
15+
use ONGR\ElasticsearchBundle\Annotation as ES;
16+
17+
/**
18+
* test document for unit testing of DocumentParser class
19+
*
20+
* @ES\Index(alias="testdocument")
21+
*/
22+
class TestDocument
23+
{
24+
// This con't is only as a helper.
25+
CONST INDEX_NAME = 'testdocument';
26+
27+
/**
28+
* @ES\Id()
29+
*/
30+
public $id;
31+
32+
/**
33+
* @ES\Property(
34+
* type="text",
35+
* name="title",
36+
* fields={
37+
* "raw"={"type"="keyword"},
38+
* "increment"={"type"="text", "analyzer"="incrementalAnalyzer"},
39+
* "sorting"={"type"="keyword", "normalizer"="lowercase_normalizer"}
40+
* }
41+
* )
42+
*/
43+
public $title;
44+
}

0 commit comments

Comments
 (0)