Skip to content

Commit 555bf15

Browse files
committed
Fixed problem with indexing a multilanguage field larger than 32k
Added property mapping option to specify the mapping of the 'default' field in multilanguage properties
1 parent 64285f0 commit 555bf15

File tree

6 files changed

+70
-11
lines changed

6 files changed

+70
-11
lines changed

Annotation/Property.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* Annotation used to check mapping type during the parsing process.
99
*
1010
* @Annotation
11+
*
1112
* @Target("PROPERTY")
1213
*/
1314
final class Property implements DumperInterface
@@ -35,6 +36,13 @@ final class Property implements DumperInterface
3536
*/
3637
public $multilanguage;
3738

39+
/**
40+
* Override mapping for the 'default' language field of multilanguage properties
41+
*
42+
* @var array
43+
*/
44+
public $multilanguageDefaultOptions;
45+
3846
/**
3947
* The object name must be defined, if type is 'object' or 'nested'
4048
*

Mapping/DocumentParser.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ public function getPropertiesMetadata(\ReflectionClass $documentReflection)
130130
$propertyAnnotation = $propertyAnnotation ?: $this->reader->getPropertyAnnotation($property, Score::class);
131131

132132
// Ignore class properties without any recognized annotation
133-
if ($propertyAnnotation === null) {
133+
if (null === $propertyAnnotation) {
134134
continue;
135135
}
136136

@@ -231,10 +231,11 @@ private function getDocumentType(\ReflectionClass $documentReflection)
231231
*
232232
* @param \ReflectionProperty $property
233233
*
234-
* @return Property
234+
* @return Property|null
235235
*/
236236
private function getPropertyAnnotationData($property)
237237
{
238+
/** @var Property $annotation */
238239
$annotation = $this->reader->getPropertyAnnotation($property, Property::class);
239240

240241
return $annotation;
@@ -332,10 +333,11 @@ private function getProperties(\ReflectionClass $documentReflection, array $inde
332333
foreach ($this->languageProvider->getLanguages() as $language) {
333334
$mapping[$propertyAnnotation->name.$this->languageSeparator.$language] = $this->getPropertyMapping($propertyAnnotation, $language, $indexAnalyzers);
334335
}
335-
// TODO: The application should decide whether it wants to use a default field at all and set its mapping on a global base (or per property?)
336+
// TODO: The application should decide whether it wants to use a default field at all and set its mapping on a global base
336337
// The custom mapping from the application should be set here, using perhaps some kind of decorator
337-
$mapping[$propertyAnnotation->name.$this->languageSeparator.Property::DEFAULT_LANG_SUFFIX] = [
338+
$mapping[$propertyAnnotation->name.$this->languageSeparator.Property::DEFAULT_LANG_SUFFIX] = $propertyAnnotation->multilanguageDefaultOptions ?: [
338339
'type' => 'keyword',
340+
'ignore_above' => 256,
339341
];
340342
} else {
341343
$mapping[$propertyAnnotation->name] = $this->getPropertyMapping($propertyAnnotation, null, $indexAnalyzers);

Resources/doc/i18n.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ That service must have a method returning an array of language codes that will b
3737
* name="title",
3838
* type="text",
3939
* multilanguage=true,
40+
* multilanguageDefaultOptions={
41+
* "type":"text",
42+
* "index":false
43+
* },
4044
* options={
4145
* "analyzer":"{lang}_analyzer",
4246
* }
@@ -46,6 +50,8 @@ That service must have a method returning an array of language codes that will b
4650
```
4751
> Note the use of **{lang}** in the analyzer declaration. It is going to be replaced by a respective language code at runtime.
4852
53+
Specifying `multilanguageDefaultOptions` is entirely optional. If it is specified, it will override the default mapping for the `title-default` field.
54+
4955
* Then, you must make sure you have all language-specific analyzers defined in your index config:
5056
```
5157
indices:

Resources/doc/mapping.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ Sometimes, you may have a field that is available in more than one language. Thi
8383
* name="name",
8484
* type="text",
8585
* multilanguage=true,
86+
* multilanguageDefaultOptions={
87+
* "type":"text",
88+
* "index":false
89+
* },
8690
* options={
8791
* "analyzer":"{lang}_analyzer",
8892
* }
@@ -92,7 +96,10 @@ Sometimes, you may have a field that is available in more than one language. Thi
9296
```
9397
> Note the use of `{lang}` placeholder in the options.
9498
95-
When you have a property definition like that, there will not be a field `name` in your index, but instead there will be `name-en`, `name-fr`, `name-de`, etc. where the suffixes are taken from the available languages in your application. You may also use the special `{lang}` placeholder in the options array, as often you would need to specify different analyzers, depending on the language. For more information on how that works, see [multilanguage support](i18n.md).
99+
When you have a property definition like that, there will not be a field `name` in your index, but instead there will be `name-en`, `name-fr`, `name-de`, etc. where the suffixes are taken from the available languages in your application.
100+
There will also be a field `name-default`, whose default mapping of `type:keyword;ignore_above:256` you can optionally override by specifying alternative `multilanguageDefaultOptions`.
101+
102+
You may also use the special `{lang}` placeholder in the options array, as often you would need to specify different analyzers, depending on the language. For more information on how that works, see [multilanguage support](i18n.md).
96103

97104
### Meta property annotations
98105

Tests/Functional/Mapping/DocumentParserTest.php

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,20 @@ public function testParse()
166166
'ml_info-default' =>
167167
[
168168
'type' => 'keyword',
169+
'ignore_above' => 256,
170+
],
171+
'ml_more_info-en' =>
172+
[
173+
'type' => 'text',
174+
],
175+
'ml_more_info-fr' =>
176+
[
177+
'type' => 'text',
178+
],
179+
'ml_more_info-default' =>
180+
[
181+
'type' => 'text',
182+
'index' => false,
169183
],
170184
'pieces_count' =>
171185
[
@@ -319,12 +333,19 @@ public function testParse()
319333
'propertyAccess' => 1,
320334
],
321335
'ml_info' =>
322-
[
323-
'propertyName' => 'mlInfo',
324-
'type' => 'text',
325-
'multilanguage' => true,
326-
'propertyAccess' => 1,
327-
],
336+
[
337+
'propertyName' => 'mlInfo',
338+
'type' => 'text',
339+
'multilanguage' => true,
340+
'propertyAccess' => 1,
341+
],
342+
'ml_more_info' =>
343+
[
344+
'propertyName' => 'mlMoreInfo',
345+
'type' => 'text',
346+
'multilanguage' => true,
347+
'propertyAccess' => 1,
348+
],
328349
'pieces_count' =>
329350
[
330351
'propertyName' => 'tokenPiecesCount',

Tests/app/fixture/Acme/BarBundle/Document/Product.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,21 @@ class Product extends AbstractDocument
9696
*/
9797
public $mlInfo;
9898

99+
/**
100+
* @var MLProperty
101+
*
102+
* @ES\Property(
103+
* name="ml_more_info",
104+
* type="text",
105+
* multilanguage=true,
106+
* multilanguageDefaultOptions={
107+
* "type":"text",
108+
* "index":false,
109+
* }
110+
* )
111+
*/
112+
public $mlMoreInfo;
113+
99114
/**
100115
* @var int
101116
*

0 commit comments

Comments
 (0)