Skip to content

Commit 6c77774

Browse files
committed
Merge branch '1.x' into add-common-search-adapter
# Conflicts: # tests/Functional/SearchIndex/IndexQueueTest.php # tests/Support/Helper/GenericDataIndex.php
2 parents 553aede + bee02be commit 6c77774

File tree

6 files changed

+179
-16
lines changed

6 files changed

+179
-16
lines changed

doc/04_Searching_For_Data_In_Index/05_Search_Modifiers/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ $search->addModifier(new ParentIdFilter(1))
3434
| Modifier | Modifier Category | Description |
3535
|-------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
3636
| [ElementKeySearch](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/FullTextSearch/ElementKeySearch.php) | Full text search | Search by element key like in the studio UI with [wildcard support](#wildcard-support). |
37-
| [WildcardSearch](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/FullTextSearch/WildcardSearch.php) | Full text search | Filter text fields based on search terms with [wildcard support](#wildcard-support) and [PQL field name resolution support](#pql-field-name-resolution). |
37+
| [FullTextSearch](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/FullTextSearch/FullTextSearch.php) | Full text search | Search on all element fields by value with [simple query string syntax](https://opensearch.org/docs/latest/query-dsl/full-text/simple-query-string/#simple-query-string-syntax). |
38+
| [WildcardSearch](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/FullTextSearch/WildcardSearch.php) | Full text search | Filter text fields based on search terms with [wildcard support](#wildcard-support) and [PQL field name resolution support](#pql-field-name-resolution). |
3839

3940

4041
### Dependencies
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* Pimcore
6+
*
7+
* This source file is available under two different licenses:
8+
* - GNU General Public License version 3 (GPLv3)
9+
* - Pimcore Commercial License (PCL)
10+
* Full copyright and license information is available in
11+
* LICENSE.md which is distributed with this source code.
12+
*
13+
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
14+
* @license http://www.pimcore.org/license GPLv3 and PCL
15+
*/
16+
17+
namespace Pimcore\Bundle\GenericDataIndexBundle\Model\OpenSearch\Query;
18+
19+
use Pimcore\Bundle\GenericDataIndexBundle\Enum\SearchIndex\OpenSearch\ConditionType;
20+
21+
final class SimpleQueryStringFilter extends BoolQuery implements AsSubQueryInterface
22+
{
23+
public function __construct(
24+
private readonly string $term
25+
) {
26+
parent::__construct([
27+
ConditionType::FILTER->value => [
28+
'simple_query_string' => [
29+
'query' => $this->term,
30+
],
31+
],
32+
]);
33+
}
34+
35+
public function getTerm(): string
36+
{
37+
return $this->term;
38+
}
39+
40+
public function toArrayAsSubQuery(): array
41+
{
42+
return [
43+
'simple_query_string' => [
44+
'query' => $this->term,
45+
],
46+
];
47+
}
48+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* Pimcore
6+
*
7+
* This source file is available under two different licenses:
8+
* - GNU General Public License version 3 (GPLv3)
9+
* - Pimcore Commercial License (PCL)
10+
* Full copyright and license information is available in
11+
* LICENSE.md which is distributed with this source code.
12+
*
13+
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
14+
* @license http://www.pimcore.org/license GPLv3 and PCL
15+
*/
16+
17+
namespace Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\FullTextSearch;
18+
19+
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\SearchModifierInterface;
20+
21+
final readonly class FullTextSearch implements SearchModifierInterface
22+
{
23+
public function __construct(
24+
private string $searchTerm
25+
) {
26+
}
27+
28+
public function getSearchTerm(): string
29+
{
30+
return $this->searchTerm;
31+
}
32+
}

src/SearchIndexAdapter/OpenSearch/Search/Modifier/FullTextSearch/FullTextSearchHandlers.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
use Pimcore\Bundle\GenericDataIndexBundle\Enum\SearchIndex\FieldCategory\SystemField;
2121
use Pimcore\Bundle\GenericDataIndexBundle\Enum\SearchIndex\OpenSearch\WildcardFilterMode;
2222
use Pimcore\Bundle\GenericDataIndexBundle\Model\OpenSearch\Modifier\SearchModifierContextInterface;
23+
use Pimcore\Bundle\GenericDataIndexBundle\Model\OpenSearch\Query\SimpleQueryStringFilter;
2324
use Pimcore\Bundle\GenericDataIndexBundle\Model\OpenSearch\Query\WildcardFilter;
2425
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\FullTextSearch\ElementKeySearch;
26+
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\FullTextSearch\FullTextSearch;
2527
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\FullTextSearch\WildcardSearch;
2628
use Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\SearchPqlFieldNameTransformationServiceInterface;
2729

@@ -80,4 +82,16 @@ public function handleWildcardSearch(
8082
)
8183
);
8284
}
85+
86+
#[AsSearchModifierHandler]
87+
public function handleMultiMatchSearch(
88+
FullTextSearch $fullValueSearch,
89+
SearchModifierContextInterface $context
90+
): void {
91+
if (empty($fullValueSearch->getSearchTerm())) {
92+
return;
93+
}
94+
95+
$context->getSearch()->addQuery(new SimpleQueryStringFilter($fullValueSearch->getSearchTerm()));
96+
}
8397
}

src/Service/SearchIndex/IndexService/ElementTypeAdapter/DataObjectTypeAdapter.php

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use InvalidArgumentException;
2323
use Pimcore\Bundle\GenericDataIndexBundle\Enum\SearchIndex\ElementType;
2424
use Pimcore\Bundle\GenericDataIndexBundle\Enum\SearchIndex\IndexName;
25+
use Pimcore\Bundle\GenericDataIndexBundle\Enum\SearchIndex\IndexQueueOperation;
2526
use Pimcore\Bundle\GenericDataIndexBundle\Event\DataObject\UpdateFolderIndexDataEvent;
2627
use Pimcore\Bundle\GenericDataIndexBundle\Event\DataObject\UpdateIndexDataEvent;
2728
use Pimcore\Bundle\GenericDataIndexBundle\Event\UpdateIndexDataEventInterface;
@@ -105,22 +106,10 @@ public function getRelatedItemsOnUpdateQuery(
105106
}
106107

107108
if (!$element->getClass()->getAllowInherit()) {
108-
if ($includeElement) {
109-
return $this->dbConnection->createQueryBuilder()
110-
->select([
111-
$element->getId(),
112-
"'" . ElementType::DATA_OBJECT->value . "'",
113-
'className',
114-
"'$operation'",
115-
"'$operationTime'",
116-
'0',
117-
])
118-
->from('objects') // just a dummy query to fit into the query builder interface
119-
->where('id = :id')
120-
->setMaxResults(1)
121-
->setParameter('id', $element->getId());
122-
}
109+
return $this->getRelatedItemsQueryBuilder($element, $operation, $operationTime, $includeElement);
110+
}
123111

112+
if ($operation !== IndexQueueOperation::UPDATE->value) {
124113
return null;
125114
}
126115

@@ -163,4 +152,45 @@ public function getUpdateIndexDataEvent(
163152

164153
throw new InvalidArgumentException('Element must be instance of ' . AbstractObject::class);
165154
}
155+
156+
private function getRelatedItemsQueryBuilder(
157+
Concrete $element,
158+
string $operation,
159+
int $operationTime,
160+
bool $includeElement = false
161+
): ?QueryBuilder {
162+
if (!$includeElement) {
163+
return null;
164+
}
165+
166+
$queryBuilder = $this->dbConnection->createQueryBuilder()
167+
->select($this->getSelectParametersByOperation($element, $operation, $operationTime))
168+
->setMaxResults(1);
169+
170+
if ($operation === IndexQueueOperation::DELETE->value) {
171+
return $queryBuilder->from('DUAL');
172+
}
173+
174+
return $queryBuilder
175+
->from('objects')
176+
->where('id = :id')
177+
->setParameter('id', $element->getId());
178+
}
179+
180+
private function getSelectParametersByOperation(Concrete $element, string $operation, int $operationTime): array
181+
{
182+
$classId = 'className';
183+
if ($operation === IndexQueueOperation::DELETE->value) {
184+
$classId = "'" . $element->getClassId() . "'";
185+
}
186+
187+
return [
188+
$element->getId(),
189+
"'" . ElementType::DATA_OBJECT->value . "'",
190+
$classId,
191+
"'$operation'",
192+
"'$operationTime'",
193+
'0',
194+
];
195+
}
166196
}

tests/Functional/Search/Modifier/FullTextSearch/FullTextSearchTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
namespace Pimcore\Bundle\GenericDataIndexBundle\Tests\Functional\Search\Modifier\FullTextSearch;
1818

1919
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\FullTextSearch\ElementKeySearch;
20+
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\FullTextSearch\FullTextSearch;
2021
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\FullTextSearch\WildcardSearch;
2122
use Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\Asset\AssetSearchServiceInterface;
2223
use Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\SearchProviderInterface;
@@ -178,4 +179,41 @@ public function testWildcardSearch(): void
178179
$searchResult = $searchService->search($assetSearch);
179180
$this->assertEquals([], $searchResult->getIds());
180181
}
182+
183+
public function testFullTextSearch(): void
184+
{
185+
$asset = TestHelper::createImageAsset();
186+
$asset->setFilename('Asset 1.jpg')->setKey('123')->save();
187+
$asset2 = TestHelper::createImageAsset();
188+
$asset2->setFilename('Asset 2.jpg')->setKey('456')->save();
189+
190+
/** @var AssetSearchServiceInterface $searchService */
191+
$searchService = $this->tester->grabService('generic-data-index.test.service.asset-search-service');
192+
/** @var SearchProviderInterface $searchProvider */
193+
$searchProvider = $this->tester->grabService(SearchProviderInterface::class);
194+
195+
$assetSearch = $searchProvider
196+
->createAssetSearch()
197+
->addModifier(new FullTextSearch($asset->getKey()))
198+
;
199+
$this->assertEquals([$asset->getId()], $searchService->search($assetSearch)->getIds());
200+
201+
$assetSearch = $searchProvider
202+
->createAssetSearch()
203+
->addModifier(new FullTextSearch($asset2->getKey()))
204+
;
205+
$this->assertEquals([$asset2->getId()], $searchService->search($assetSearch)->getIds());
206+
207+
$assetSearch = $searchProvider
208+
->createAssetSearch()
209+
->addModifier(new FullTextSearch('asset'))
210+
;
211+
$this->assertEquals([$asset->getId(), $asset2->getId()], $searchService->search($assetSearch)->getIds());
212+
213+
$assetSearch = $searchProvider
214+
->createAssetSearch()
215+
->addModifier(new FullTextSearch($asset2->getFilename()))
216+
;
217+
$this->assertEquals([$asset2->getId()], $searchService->search($assetSearch)->getIds());
218+
}
181219
}

0 commit comments

Comments
 (0)