Skip to content

Commit 12aadf1

Browse files
author
Oleksandr Iegorov
committed
Merge branch 'MAGETWO-97830' of https://github.com/magento-tango/magento2ce into PR-0204
2 parents f60063a + 383d6bc commit 12aadf1

File tree

19 files changed

+413
-81
lines changed

19 files changed

+413
-81
lines changed

app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public function getFields(array $context = []): array
126126
foreach ($groups as $group) {
127127
$groupPriceKey = $this->fieldNameResolver->getFieldName(
128128
$priceAttribute,
129-
['customerGroupId' => $group->getId(), 'websiteId' => $context['websiteId']]
129+
array_merge($context, ['customerGroupId' => $group->getId()])
130130
);
131131
$allAttributes[$groupPriceKey] = [
132132
'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_FLOAT),

app/code/Magento/Elasticsearch/SearchAdapter/Aggregation/Builder/Term.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,29 @@
88
use Magento\Framework\Search\Request\BucketInterface as RequestBucketInterface;
99
use Magento\Framework\Search\Dynamic\DataProviderInterface;
1010

11+
/**
12+
* Builder for term buckets.
13+
*/
1114
class Term implements BucketBuilderInterface
1215
{
1316
/**
14-
* {@inheritdoc}
17+
* @inheritdoc
1518
*/
1619
public function build(
1720
RequestBucketInterface $bucket,
1821
array $dimensions,
1922
array $queryResult,
2023
DataProviderInterface $dataProvider
2124
) {
25+
$buckets = $queryResult['aggregations'][$bucket->getName()]['buckets'] ?? [];
2226
$values = [];
23-
foreach ($queryResult['aggregations'][$bucket->getName()]['buckets'] as $resultBucket) {
27+
foreach ($buckets as $resultBucket) {
2428
$values[$resultBucket['key']] = [
2529
'value' => $resultBucket['key'],
2630
'count' => $resultBucket['doc_count'],
2731
];
2832
}
33+
2934
return $values;
3035
}
3136
}

app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55
*/
66
namespace Magento\Elasticsearch\SearchAdapter\Query\Builder;
77

8+
use Magento\Elasticsearch\SearchAdapter\Query\ValueTransformerPool;
9+
use Magento\Framework\App\ObjectManager;
810
use Magento\Framework\Search\Request\Query\BoolExpression;
911
use Magento\Framework\Search\Request\QueryInterface as RequestQueryInterface;
1012
use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface;
1113
use Magento\Framework\Search\Adapter\Preprocessor\PreprocessorInterface;
1214

15+
/**
16+
* Builder for match query.
17+
*/
1318
class Match implements QueryInterface
1419
{
1520
/**
@@ -23,24 +28,35 @@ class Match implements QueryInterface
2328
private $fieldMapper;
2429

2530
/**
31+
* @deprecated
32+
* @see \Magento\Elasticsearch\SearchAdapter\Query\ValueTransformer\TextTransformer
2633
* @var PreprocessorInterface[]
2734
*/
2835
protected $preprocessorContainer;
2936

37+
/**
38+
* @var ValueTransformerPool
39+
*/
40+
private $valueTransformerPool;
41+
3042
/**
3143
* @param FieldMapperInterface $fieldMapper
3244
* @param PreprocessorInterface[] $preprocessorContainer
45+
* @param ValueTransformerPool|null $valueTransformerPool
3346
*/
3447
public function __construct(
3548
FieldMapperInterface $fieldMapper,
36-
array $preprocessorContainer
49+
array $preprocessorContainer,
50+
ValueTransformerPool $valueTransformerPool = null
3751
) {
3852
$this->fieldMapper = $fieldMapper;
3953
$this->preprocessorContainer = $preprocessorContainer;
54+
$this->valueTransformerPool = $valueTransformerPool ?? ObjectManager::getInstance()
55+
->get(ValueTransformerPool::class);
4056
}
4157

4258
/**
43-
* {@inheritdoc}
59+
* @inheritdoc
4460
*/
4561
public function build(array $selectQuery, RequestQueryInterface $requestQuery, $conditionType)
4662
{
@@ -61,16 +77,14 @@ public function build(array $selectQuery, RequestQueryInterface $requestQuery, $
6177
}
6278

6379
/**
80+
* Prepare query.
81+
*
6482
* @param string $queryValue
6583
* @param string $conditionType
6684
* @return array
6785
*/
6886
protected function prepareQuery($queryValue, $conditionType)
6987
{
70-
$queryValue = $this->escape($queryValue);
71-
foreach ($this->preprocessorContainer as $preprocessor) {
72-
$queryValue = $preprocessor->process($queryValue);
73-
}
7488
$condition = $conditionType === BoolExpression::QUERY_CONDITION_NOT ?
7589
self::QUERY_CONDITION_MUST_NOT : $conditionType;
7690
return [
@@ -99,21 +113,34 @@ protected function buildQueries(array $matches, array $queryValue)
99113

100114
// Checking for quoted phrase \"phrase test\", trim escaped surrounding quotes if found
101115
$count = 0;
102-
$value = preg_replace('#^\\\\"(.*)\\\\"$#m', '$1', $queryValue['value'], -1, $count);
116+
$value = preg_replace('#^"(.*)"$#m', '$1', $queryValue['value'], -1, $count);
103117
$condition = ($count) ? 'match_phrase' : 'match';
104118

119+
$attributesTypes = $this->fieldMapper->getAllAttributesTypes();
120+
$transformedTypes = [];
105121
foreach ($matches as $match) {
106122
$resolvedField = $this->fieldMapper->getFieldName(
107123
$match['field'],
108124
['type' => FieldMapperInterface::TYPE_QUERY]
109125
);
126+
$valueTransformer = $this->valueTransformerPool->get($attributesTypes[$resolvedField]['type'] ?? 'text');
127+
$valueTransformerHash = \spl_object_hash($valueTransformer);
128+
if (!isset($transformedTypes[$valueTransformerHash])) {
129+
$transformedTypes[$valueTransformerHash] = $valueTransformer->transform($value);
130+
}
131+
$transformedValue = $transformedTypes[$valueTransformerHash];
132+
if (null === $transformedValue) {
133+
//Value is incompatible with this field type.
134+
continue;
135+
}
136+
110137
$conditions[] = [
111138
'condition' => $queryValue['condition'],
112139
'body' => [
113140
$condition => [
114141
$resolvedField => [
115-
'query' => $value,
116-
'boost' => isset($match['boost']) ? $match['boost'] : 1,
142+
'query' => $transformedValue,
143+
'boost' => $match['boost'] ?? 1,
117144
],
118145
],
119146
],
@@ -124,18 +151,15 @@ protected function buildQueries(array $matches, array $queryValue)
124151
}
125152

126153
/**
127-
* Cut trailing plus or minus sign, and @ symbol, using of which causes InnoDB to report a syntax error.
128-
* @link https://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html Fulltext-boolean search docs.
129-
*
130154
* Escape a value for special query characters such as ':', '(', ')', '*', '?', etc.
131155
*
156+
* @deprecated
157+
* @see \Magento\Elasticsearch\SearchAdapter\Query\ValueTransformer\TextTransformer
132158
* @param string $value
133159
* @return string
134160
*/
135161
protected function escape($value)
136162
{
137-
$value = preg_replace('/@+|[@+-]+$/', '', $value);
138-
139163
$pattern = '/(\+|-|&&|\|\||!|\(|\)|\{|}|\[|]|\^|"|~|\*|\?|:|\\\)/';
140164
$replace = '\\\$1';
141165

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Elasticsearch\SearchAdapter\Query\ValueTransformer;
9+
10+
use Magento\Elasticsearch\Model\Adapter\FieldType\Date;
11+
use Magento\Elasticsearch\SearchAdapter\Query\ValueTransformerInterface;
12+
13+
/**
14+
* Value transformer for date type fields.
15+
*/
16+
class DateTransformer implements ValueTransformerInterface
17+
{
18+
/**
19+
* @var Date
20+
*/
21+
private $dateFieldType;
22+
23+
/**
24+
* @param Date $dateFieldType
25+
*/
26+
public function __construct(Date $dateFieldType)
27+
{
28+
$this->dateFieldType = $dateFieldType;
29+
}
30+
31+
/**
32+
* @inheritdoc
33+
*/
34+
public function transform(string $value): ?string
35+
{
36+
try {
37+
$formattedDate = $this->dateFieldType->formatDate(null, $value);
38+
} catch (\Exception $e) {
39+
$formattedDate = null;
40+
}
41+
42+
return $formattedDate;
43+
}
44+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Elasticsearch\SearchAdapter\Query\ValueTransformer;
9+
10+
use Magento\Elasticsearch\SearchAdapter\Query\ValueTransformerInterface;
11+
12+
/**
13+
* Value transformer for float type fields.
14+
*/
15+
class FloatTransformer implements ValueTransformerInterface
16+
{
17+
/**
18+
* @inheritdoc
19+
*/
20+
public function transform(string $value): ?float
21+
{
22+
return \is_numeric($value) ? (float) $value : null;
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Elasticsearch\SearchAdapter\Query\ValueTransformer;
9+
10+
use Magento\Elasticsearch\SearchAdapter\Query\ValueTransformerInterface;
11+
12+
/**
13+
* Value transformer for integer type fields.
14+
*/
15+
class IntegerTransformer implements ValueTransformerInterface
16+
{
17+
/**
18+
* @inheritdoc
19+
*/
20+
public function transform(string $value): ?int
21+
{
22+
return \is_numeric($value) ? (int) $value : null;
23+
}
24+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Elasticsearch\SearchAdapter\Query\ValueTransformer;
9+
10+
use Magento\Elasticsearch\SearchAdapter\Query\ValueTransformerInterface;
11+
use Magento\Framework\Search\Adapter\Preprocessor\PreprocessorInterface;
12+
13+
/**
14+
* Value transformer for fields with text types.
15+
*/
16+
class TextTransformer implements ValueTransformerInterface
17+
{
18+
/**
19+
* @var PreprocessorInterface[]
20+
*/
21+
private $preprocessors;
22+
23+
/**
24+
* @param PreprocessorInterface[] $preprocessors
25+
*/
26+
public function __construct(array $preprocessors = [])
27+
{
28+
foreach ($preprocessors as $preprocessor) {
29+
if (!$preprocessor instanceof PreprocessorInterface) {
30+
throw new \InvalidArgumentException(
31+
\sprintf('"%s" is not a instance of ValueTransformerInterface.', get_class($preprocessor))
32+
);
33+
}
34+
}
35+
36+
$this->preprocessors = $preprocessors;
37+
}
38+
39+
/**
40+
* @inheritdoc
41+
*/
42+
public function transform(string $value): string
43+
{
44+
$value = $this->escape($value);
45+
foreach ($this->preprocessors as $preprocessor) {
46+
$value = $preprocessor->process($value);
47+
}
48+
49+
return $value;
50+
}
51+
52+
/**
53+
* Escape a value for special query characters such as ':', '(', ')', '*', '?', etc.
54+
*
55+
* @param string $value
56+
* @return string
57+
*/
58+
private function escape(string $value): string
59+
{
60+
$pattern = '/(\+|-|&&|\|\||!|\(|\)|\{|}|\[|]|\^|"|~|\*|\?|:|\\\)/';
61+
$replace = '\\\$1';
62+
63+
return preg_replace($pattern, $replace, $value);
64+
}
65+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Elasticsearch\SearchAdapter\Query;
9+
10+
/**
11+
* Value transformer of search term for matching with ES field types.
12+
*/
13+
interface ValueTransformerInterface
14+
{
15+
/**
16+
* Transform value according to field type.
17+
*
18+
* @param string $value
19+
* @return mixed
20+
*/
21+
public function transform(string $value);
22+
}

0 commit comments

Comments
 (0)