From 4028a27c78db4f3d136f59bf017e544423911122 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Sat, 11 Jan 2025 12:35:54 +0100 Subject: [PATCH 01/31] Merge ElasticSearch and Solr custom criterion, sort clause and aggregation Criteria, sort clauses and aggregations don't depend on the search engine, only their visitors and other handlers do. --- .../custom/config/aggregation_services.yaml | 57 +++++++++++++ .../config/criterion_services.yaml | 5 ++ .../config/field_mapper_services.yaml | 0 .../config/group_resolver_services.yaml | 0 .../config/packages/elasticsearch-en.yaml | 0 .../config/packages/elasticsearch.yaml | 0 .../config/sort_clause_services.yaml | 5 ++ .../ContentTypeGroupGroupResolver.php | 0 ...iorityRangeAggregationResultExtractor.php} | 3 +- .../PriorityRangeAggregationVisitor.php} | 3 +- .../Aggregation}/PriorityRangeAggregation.php | 2 +- ...iorityRangeAggregationResultExtractor.php} | 3 +- .../Solr/PriorityRangeAggregationVisitor.php | 1 + .../CameraManufacturerCriterion.php | 2 +- .../CameraManufacturerVisitor.php | 3 +- .../Solr/CameraManufacturerVisitor.php | 3 +- .../SortClause/Elasticsearch/ScoreVisitor.php | 1 + .../src/Query/SortClause}/ScoreSortClause.php | 2 +- .../Query/SortClause/Solr/ScoreVisitor.php | 3 +- .../WebinarEventTitleFulltextFieldMapper.php | 0 .../config/aggregation_services.yaml | 10 --- .../PriorityRangeAggregation.php | 12 --- .../CameraManufacturerCriterion.php | 36 -------- .../Elasticsearch/ScoreSortClause.php | 16 ---- .../solr/config/aggregation_services.yaml | 10 --- .../solr/config/criterion_services.yaml | 5 -- .../solr/config/sort_clause_services.yaml | 5 -- .../create_custom_aggregation.md | 85 ++++++------------- .../create_custom_search_criterion.md | 34 +++----- .../create_custom_sort_clause.md | 34 +++----- ...customize_elasticsearch_index_structure.md | 7 +- .../solr_document_field_mappers.md | 4 +- .../configure_elastic_search.md | 2 +- 33 files changed, 137 insertions(+), 216 deletions(-) create mode 100644 code_samples/search/custom/config/aggregation_services.yaml rename code_samples/search/{elasticsearch => custom}/config/criterion_services.yaml (53%) rename code_samples/search/{solr => custom}/config/field_mapper_services.yaml (100%) rename code_samples/search/{elasticsearch => custom}/config/group_resolver_services.yaml (100%) rename code_samples/search/{elasticsearch => custom}/config/packages/elasticsearch-en.yaml (100%) rename code_samples/search/{elasticsearch => custom}/config/packages/elasticsearch.yaml (100%) rename code_samples/search/{elasticsearch => custom}/config/sort_clause_services.yaml (53%) rename code_samples/search/{elasticsearch => custom}/src/GroupResolver/ContentTypeGroupGroupResolver.php (100%) rename code_samples/search/{elasticsearch/src/Query/Aggregation/Elasticsearch/PriorityAggregationResultExtractor.php => custom/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregationResultExtractor.php} (88%) rename code_samples/search/{elasticsearch/src/Query/Aggregation/Elasticsearch/PriorityAggregationVisitor.php => custom/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregationVisitor.php} (92%) rename code_samples/search/{solr/src/Query/Aggregation/Solr => custom/src/Query/Aggregation}/PriorityRangeAggregation.php (89%) rename code_samples/search/{solr/src/Query/Aggregation/Solr/PriorityAggregationResultExtractor.php => custom/src/Query/Aggregation/Solr/PriorityRangeAggregationResultExtractor.php} (90%) rename code_samples/search/{solr => custom}/src/Query/Aggregation/Solr/PriorityRangeAggregationVisitor.php (96%) rename code_samples/search/{solr/src/Query/Criterion/Solr => custom/src/Query/Criterion}/CameraManufacturerCriterion.php (96%) rename code_samples/search/{elasticsearch => custom}/src/Query/Criterion/Elasticsearch/CameraManufacturerVisitor.php (86%) rename code_samples/search/{solr => custom}/src/Query/Criterion/Solr/CameraManufacturerVisitor.php (86%) rename code_samples/search/{elasticsearch => custom}/src/Query/SortClause/Elasticsearch/ScoreVisitor.php (95%) rename code_samples/search/{solr/src/Query/SortClause/Solr => custom/src/Query/SortClause}/ScoreSortClause.php (90%) rename code_samples/search/{solr => custom}/src/Query/SortClause/Solr/ScoreVisitor.php (82%) rename code_samples/search/{solr => custom}/src/Search/FieldMapper/WebinarEventTitleFulltextFieldMapper.php (100%) delete mode 100644 code_samples/search/elasticsearch/config/aggregation_services.yaml delete mode 100644 code_samples/search/elasticsearch/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregation.php delete mode 100644 code_samples/search/elasticsearch/src/Query/Criterion/Elasticsearch/CameraManufacturerCriterion.php delete mode 100644 code_samples/search/elasticsearch/src/Query/SortClause/Elasticsearch/ScoreSortClause.php delete mode 100644 code_samples/search/solr/config/aggregation_services.yaml delete mode 100644 code_samples/search/solr/config/criterion_services.yaml delete mode 100644 code_samples/search/solr/config/sort_clause_services.yaml diff --git a/code_samples/search/custom/config/aggregation_services.yaml b/code_samples/search/custom/config/aggregation_services.yaml new file mode 100644 index 0000000000..6653219743 --- /dev/null +++ b/code_samples/search/custom/config/aggregation_services.yaml @@ -0,0 +1,57 @@ +services: + app.search.solr.query.aggregation_visitor.priority_range_aggregation: + class: Ibexa\Solr\Query\Common\AggregationVisitor\PriorityRangeAggregationVisitor + factory: [ '@Ibexa\Solr\Query\Common\AggregationVisitor\Factory\ContentFieldAggregationVisitorFactory', 'createRangeAggregationVisitor' ] + arguments: + $aggregationClass: 'App\Query\Aggregation\Solr\PriorityRangeAggregation' + $searchIndexFieldName: 'priority_i' + tags: + - { name: ibexa.search.solr.query.content.aggregation.visitor } + - { name: ibexa.search.solr.query.location.aggregation.visitor } + + app.search.elasticsearch.query.aggregation_visitor.priority_range_aggregation: + class: Ibexa\Elasticsearch\Query\AggregationVisitor\PriorityRangeAggregationVisitor + factory: [ '@Ibexa\Elasticsearch\Query\AggregationVisitor\Factory\SearchFieldAggregationVisitorFactory', 'createRangeAggregationVisitor' ] + arguments: + $aggregationClass: 'App\Query\Aggregation\Elasticsearch\PriorityRangeAggregation' + $searchIndexFieldName: 'priority_i' + tags: + - { name: ibexa.search.elasticsearch.query.location.aggregation.visitor } + - { name: ibexa.search.elasticsearch.query.content.aggregation.visitor } + + app.search.solr.query.aggregation_result_extractor.priority_range_aggregation: + class: Ibexa\Solr\ResultExtractor\AggregationResultExtractor\RangeAggregationResultExtractor + arguments: + $aggregationClass: 'App\Query\Aggregation\Solr\PriorityRangeAggregation' + $keyMapper: 'Ibexa\Solr\ResultExtractor\AggregationResultExtractor\RangeAggregationKeyMapper\IntRangeAggregationKeyMapper' + tags: + - { name: ibexa.search.solr.query.location.aggregation.result.extractor } + - { name: ibexa.search.solr.query.content.aggregation.result.extractor } + + app.search.elasticsearch.query.aggregation_result_extractor.priority_range_aggregation: + class: Ibexa\Elasticsearch\Query\ResultExtractor\AggregationResultExtractor\RangeAggregationResultExtractor + arguments: + $aggregationClass: 'App\Query\Aggregation\Elasticsearch\PriorityRangeAggregation' + tags: + - { name: ibexa.search.elasticsearch.query.location.aggregation.result.extractor } + - { name: ibexa.search.elasticsearch.query.content.aggregation.result.extractor } + + App\Query\Aggregation\Solr\PriorityRangeAggregationVisitor: + tags: + - { name: ibexa.search.solr.query.location.aggregation.visitor } + - { name: ibexa.search.solr.query.content.aggregation.visitor } + + App\Query\Aggregation\Solr\PriorityRangeAggregationResultExtractor: + tags: + - { name: ibexa.search.solr.query.location.aggregation.result.extractor } + - { name: ibexa.search.solr.query.content.aggregation.result.extractor } + + App\Query\Aggregation\Elasticsearch\PriorityRangeAggregationVisitor: + tags: + - { name: ibexa.search.elasticsearch.query.location.aggregation.visitor } + - { name: ibexa.search.elasticsearch.query.content.aggregation.visitor } + + App\Query\Aggregation\Elasticsearch\PriorityRangeAggregationResultExtractor: + tags: + - { name: ibexa.search.elasticsearch.query.location.aggregation.result.extractor } + - { name: ibexa.search.elasticsearch.query.content.aggregation.result.extractor } diff --git a/code_samples/search/elasticsearch/config/criterion_services.yaml b/code_samples/search/custom/config/criterion_services.yaml similarity index 53% rename from code_samples/search/elasticsearch/config/criterion_services.yaml rename to code_samples/search/custom/config/criterion_services.yaml index 7c27ead21e..5619798150 100644 --- a/code_samples/search/elasticsearch/config/criterion_services.yaml +++ b/code_samples/search/custom/config/criterion_services.yaml @@ -1,4 +1,9 @@ services: + App\Query\Criterion\Solr\CameraManufacturerVisitor: + tags: + - { name: ibexa.search.solr.query.content.criterion.visitor } + - { name: ibexa.search.solr.query.location.criterion.visitor } + App\Query\Criterion\Elasticsearch\CameraManufacturerVisitor: tags: - { name: ibexa.search.elasticsearch.query.content.criterion.visitor } diff --git a/code_samples/search/solr/config/field_mapper_services.yaml b/code_samples/search/custom/config/field_mapper_services.yaml similarity index 100% rename from code_samples/search/solr/config/field_mapper_services.yaml rename to code_samples/search/custom/config/field_mapper_services.yaml diff --git a/code_samples/search/elasticsearch/config/group_resolver_services.yaml b/code_samples/search/custom/config/group_resolver_services.yaml similarity index 100% rename from code_samples/search/elasticsearch/config/group_resolver_services.yaml rename to code_samples/search/custom/config/group_resolver_services.yaml diff --git a/code_samples/search/elasticsearch/config/packages/elasticsearch-en.yaml b/code_samples/search/custom/config/packages/elasticsearch-en.yaml similarity index 100% rename from code_samples/search/elasticsearch/config/packages/elasticsearch-en.yaml rename to code_samples/search/custom/config/packages/elasticsearch-en.yaml diff --git a/code_samples/search/elasticsearch/config/packages/elasticsearch.yaml b/code_samples/search/custom/config/packages/elasticsearch.yaml similarity index 100% rename from code_samples/search/elasticsearch/config/packages/elasticsearch.yaml rename to code_samples/search/custom/config/packages/elasticsearch.yaml diff --git a/code_samples/search/elasticsearch/config/sort_clause_services.yaml b/code_samples/search/custom/config/sort_clause_services.yaml similarity index 53% rename from code_samples/search/elasticsearch/config/sort_clause_services.yaml rename to code_samples/search/custom/config/sort_clause_services.yaml index 7abda53e29..835bb47150 100644 --- a/code_samples/search/elasticsearch/config/sort_clause_services.yaml +++ b/code_samples/search/custom/config/sort_clause_services.yaml @@ -1,4 +1,9 @@ services: + App\Query\SortClause\Solr\ScoreVisitor: + tags: + - { name: ibexa.search.solr.query.content.sort_clause.visitor } + - { name: ibexa.search.solr.query.location.sort_clause.visitor } + App\Query\SortClause\Elasticsearch\ScoreVisitor: tags: - { name: ibexa.search.elasticsearch.query.content.sort_clause.visitor } diff --git a/code_samples/search/elasticsearch/src/GroupResolver/ContentTypeGroupGroupResolver.php b/code_samples/search/custom/src/GroupResolver/ContentTypeGroupGroupResolver.php similarity index 100% rename from code_samples/search/elasticsearch/src/GroupResolver/ContentTypeGroupGroupResolver.php rename to code_samples/search/custom/src/GroupResolver/ContentTypeGroupGroupResolver.php diff --git a/code_samples/search/elasticsearch/src/Query/Aggregation/Elasticsearch/PriorityAggregationResultExtractor.php b/code_samples/search/custom/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregationResultExtractor.php similarity index 88% rename from code_samples/search/elasticsearch/src/Query/Aggregation/Elasticsearch/PriorityAggregationResultExtractor.php rename to code_samples/search/custom/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregationResultExtractor.php index 05ac000d36..ab64e1be3f 100644 --- a/code_samples/search/elasticsearch/src/Query/Aggregation/Elasticsearch/PriorityAggregationResultExtractor.php +++ b/code_samples/search/custom/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregationResultExtractor.php @@ -4,12 +4,13 @@ namespace App\Query\Aggregation\Elasticsearch; +use App\Query\Aggregation\PriorityRangeAggregation; use Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation; use Ibexa\Contracts\Core\Repository\Values\Content\Search\AggregationResult; use Ibexa\Contracts\Elasticsearch\Query\AggregationResultExtractor; use Ibexa\Contracts\Elasticsearch\Query\LanguageFilter; -final class PriorityAggregationResultExtractor implements AggregationResultExtractor +final class PriorityRangeAggregationResultExtractor implements AggregationResultExtractor { public function supports(Aggregation $aggregation, LanguageFilter $languageFilter): bool { diff --git a/code_samples/search/elasticsearch/src/Query/Aggregation/Elasticsearch/PriorityAggregationVisitor.php b/code_samples/search/custom/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregationVisitor.php similarity index 92% rename from code_samples/search/elasticsearch/src/Query/Aggregation/Elasticsearch/PriorityAggregationVisitor.php rename to code_samples/search/custom/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregationVisitor.php index 10e4da76aa..219a99ce69 100644 --- a/code_samples/search/elasticsearch/src/Query/Aggregation/Elasticsearch/PriorityAggregationVisitor.php +++ b/code_samples/search/custom/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregationVisitor.php @@ -4,11 +4,12 @@ namespace App\Query\Aggregation\Elasticsearch; +use App\Query\Aggregation\PriorityRangeAggregation; use Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation; use Ibexa\Contracts\Elasticsearch\Query\AggregationVisitor; use Ibexa\Contracts\Elasticsearch\Query\LanguageFilter; -final class PriorityAggregationVisitor implements AggregationVisitor +final class PriorityRangeAggregationVisitor implements AggregationVisitor { public function supports(Aggregation $aggregation, LanguageFilter $languageFilter): bool { diff --git a/code_samples/search/solr/src/Query/Aggregation/Solr/PriorityRangeAggregation.php b/code_samples/search/custom/src/Query/Aggregation/PriorityRangeAggregation.php similarity index 89% rename from code_samples/search/solr/src/Query/Aggregation/Solr/PriorityRangeAggregation.php rename to code_samples/search/custom/src/Query/Aggregation/PriorityRangeAggregation.php index 78aff43266..8f65e1794b 100644 --- a/code_samples/search/solr/src/Query/Aggregation/Solr/PriorityRangeAggregation.php +++ b/code_samples/search/custom/src/Query/Aggregation/PriorityRangeAggregation.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Query\Aggregation\Solr; +namespace App\Query\Aggregation; use Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\AbstractRangeAggregation; use Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\LocationAggregation; diff --git a/code_samples/search/solr/src/Query/Aggregation/Solr/PriorityAggregationResultExtractor.php b/code_samples/search/custom/src/Query/Aggregation/Solr/PriorityRangeAggregationResultExtractor.php similarity index 90% rename from code_samples/search/solr/src/Query/Aggregation/Solr/PriorityAggregationResultExtractor.php rename to code_samples/search/custom/src/Query/Aggregation/Solr/PriorityRangeAggregationResultExtractor.php index 10567f6829..ba87eda5cf 100644 --- a/code_samples/search/solr/src/Query/Aggregation/Solr/PriorityAggregationResultExtractor.php +++ b/code_samples/search/custom/src/Query/Aggregation/Solr/PriorityRangeAggregationResultExtractor.php @@ -4,6 +4,7 @@ namespace App\Query\Aggregation\Solr; +use App\Query\Aggregation\PriorityRangeAggregation; use Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation; use Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\Range; use Ibexa\Contracts\Core\Repository\Values\Content\Search\AggregationResult; @@ -12,7 +13,7 @@ use Ibexa\Contracts\Solr\ResultExtractor\AggregationResultExtractor; use stdClass; -final class PriorityAggregationResultExtractor implements AggregationResultExtractor +final class PriorityRangeAggregationResultExtractor implements AggregationResultExtractor { public function canVisit(Aggregation $aggregation, array $languageFilter): bool { diff --git a/code_samples/search/solr/src/Query/Aggregation/Solr/PriorityRangeAggregationVisitor.php b/code_samples/search/custom/src/Query/Aggregation/Solr/PriorityRangeAggregationVisitor.php similarity index 96% rename from code_samples/search/solr/src/Query/Aggregation/Solr/PriorityRangeAggregationVisitor.php rename to code_samples/search/custom/src/Query/Aggregation/Solr/PriorityRangeAggregationVisitor.php index 06e77f63ea..d78f1a58f6 100644 --- a/code_samples/search/solr/src/Query/Aggregation/Solr/PriorityRangeAggregationVisitor.php +++ b/code_samples/search/custom/src/Query/Aggregation/Solr/PriorityRangeAggregationVisitor.php @@ -4,6 +4,7 @@ namespace App\Query\Aggregation\Solr; +use App\Query\Aggregation\PriorityRangeAggregation; use Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation; use Ibexa\Contracts\Solr\Query\AggregationVisitor; diff --git a/code_samples/search/solr/src/Query/Criterion/Solr/CameraManufacturerCriterion.php b/code_samples/search/custom/src/Query/Criterion/CameraManufacturerCriterion.php similarity index 96% rename from code_samples/search/solr/src/Query/Criterion/Solr/CameraManufacturerCriterion.php rename to code_samples/search/custom/src/Query/Criterion/CameraManufacturerCriterion.php index e881c45df4..91f3456369 100644 --- a/code_samples/search/solr/src/Query/Criterion/Solr/CameraManufacturerCriterion.php +++ b/code_samples/search/custom/src/Query/Criterion/CameraManufacturerCriterion.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Query\Criterion\Solr; +namespace App\Query\Criterion; use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion; use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion\Operator; diff --git a/code_samples/search/elasticsearch/src/Query/Criterion/Elasticsearch/CameraManufacturerVisitor.php b/code_samples/search/custom/src/Query/Criterion/Elasticsearch/CameraManufacturerVisitor.php similarity index 86% rename from code_samples/search/elasticsearch/src/Query/Criterion/Elasticsearch/CameraManufacturerVisitor.php rename to code_samples/search/custom/src/Query/Criterion/Elasticsearch/CameraManufacturerVisitor.php index ea9070b40d..142990bbd7 100644 --- a/code_samples/search/elasticsearch/src/Query/Criterion/Elasticsearch/CameraManufacturerVisitor.php +++ b/code_samples/search/custom/src/Query/Criterion/Elasticsearch/CameraManufacturerVisitor.php @@ -4,6 +4,7 @@ namespace App\Query\Criterion\Elasticsearch; +use App\Query\Criterion\CameraManufacturerCriterion; use Ibexa\Contracts\Core\Repository\Values\Content\Query\CriterionInterface; use Ibexa\Contracts\Elasticsearch\Query\CriterionVisitor; use Ibexa\Contracts\Elasticsearch\Query\LanguageFilter; @@ -16,7 +17,7 @@ public function supports(CriterionInterface $criterion, LanguageFilter $language } /** - * @param \App\Query\Criterion\Elasticsearch\CameraManufacturerCriterion $criterion + * @param \App\Query\Criterion\CameraManufacturerCriterion $criterion */ public function visit(CriterionVisitor $dispatcher, CriterionInterface $criterion, LanguageFilter $languageFilter): array { diff --git a/code_samples/search/solr/src/Query/Criterion/Solr/CameraManufacturerVisitor.php b/code_samples/search/custom/src/Query/Criterion/Solr/CameraManufacturerVisitor.php similarity index 86% rename from code_samples/search/solr/src/Query/Criterion/Solr/CameraManufacturerVisitor.php rename to code_samples/search/custom/src/Query/Criterion/Solr/CameraManufacturerVisitor.php index c45f1a16bf..f385d5db1d 100644 --- a/code_samples/search/solr/src/Query/Criterion/Solr/CameraManufacturerVisitor.php +++ b/code_samples/search/custom/src/Query/Criterion/Solr/CameraManufacturerVisitor.php @@ -4,6 +4,7 @@ namespace App\Query\Criterion\Solr; +use App\Query\Criterion\CameraManufacturerCriterion; use Ibexa\Contracts\Core\Repository\Values\Content\Query\CriterionInterface; use Ibexa\Contracts\Solr\Query\CriterionVisitor; @@ -15,7 +16,7 @@ public function canVisit(CriterionInterface $criterion) } /** - * @param \App\Query\Criterion\Solr\CameraManufacturerCriterion $criterion + * @param \App\Query\Criterion\CameraManufacturerCriterion $criterion */ public function visit(CriterionInterface $criterion, CriterionVisitor $subVisitor = null) { diff --git a/code_samples/search/elasticsearch/src/Query/SortClause/Elasticsearch/ScoreVisitor.php b/code_samples/search/custom/src/Query/SortClause/Elasticsearch/ScoreVisitor.php similarity index 95% rename from code_samples/search/elasticsearch/src/Query/SortClause/Elasticsearch/ScoreVisitor.php rename to code_samples/search/custom/src/Query/SortClause/Elasticsearch/ScoreVisitor.php index abc2e906e2..45a35b808c 100644 --- a/code_samples/search/elasticsearch/src/Query/SortClause/Elasticsearch/ScoreVisitor.php +++ b/code_samples/search/custom/src/Query/SortClause/Elasticsearch/ScoreVisitor.php @@ -4,6 +4,7 @@ namespace App\Query\SortClause\Elasticsearch; +use App\Query\SortClause\ScoreSortClause; use Ibexa\Contracts\Core\Repository\Values\Content\Query; use Ibexa\Contracts\Core\Repository\Values\Content\Query\SortClause; use Ibexa\Contracts\Elasticsearch\Query\LanguageFilter; diff --git a/code_samples/search/solr/src/Query/SortClause/Solr/ScoreSortClause.php b/code_samples/search/custom/src/Query/SortClause/ScoreSortClause.php similarity index 90% rename from code_samples/search/solr/src/Query/SortClause/Solr/ScoreSortClause.php rename to code_samples/search/custom/src/Query/SortClause/ScoreSortClause.php index 0ae2d69f02..8c316c18ef 100644 --- a/code_samples/search/solr/src/Query/SortClause/Solr/ScoreSortClause.php +++ b/code_samples/search/custom/src/Query/SortClause/ScoreSortClause.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Query\SortClause\Solr; +namespace App\Query\SortClause; use Ibexa\Contracts\Core\Repository\Values\Content\Query; use Ibexa\Contracts\Core\Repository\Values\Content\Query\SortClause; diff --git a/code_samples/search/solr/src/Query/SortClause/Solr/ScoreVisitor.php b/code_samples/search/custom/src/Query/SortClause/Solr/ScoreVisitor.php similarity index 82% rename from code_samples/search/solr/src/Query/SortClause/Solr/ScoreVisitor.php rename to code_samples/search/custom/src/Query/SortClause/Solr/ScoreVisitor.php index e38bfd2fc0..0daa03ad69 100644 --- a/code_samples/search/solr/src/Query/SortClause/Solr/ScoreVisitor.php +++ b/code_samples/search/custom/src/Query/SortClause/Solr/ScoreVisitor.php @@ -4,6 +4,7 @@ namespace App\Query\SortClause\Solr; +use App\Query\SortClause\ScoreSortClause; use Ibexa\Contracts\Core\Repository\Values\Content\Query\SortClause; use Ibexa\Contracts\Solr\Query\SortClauseVisitor; @@ -11,7 +12,7 @@ class ScoreVisitor extends SortClauseVisitor { public function canVisit(SortClause $sortClause): bool { - return $sortClause instanceof SortClause\Score; + return $sortClause instanceof ScoreSortClause; } public function visit(SortClause $sortClause): string diff --git a/code_samples/search/solr/src/Search/FieldMapper/WebinarEventTitleFulltextFieldMapper.php b/code_samples/search/custom/src/Search/FieldMapper/WebinarEventTitleFulltextFieldMapper.php similarity index 100% rename from code_samples/search/solr/src/Search/FieldMapper/WebinarEventTitleFulltextFieldMapper.php rename to code_samples/search/custom/src/Search/FieldMapper/WebinarEventTitleFulltextFieldMapper.php diff --git a/code_samples/search/elasticsearch/config/aggregation_services.yaml b/code_samples/search/elasticsearch/config/aggregation_services.yaml deleted file mode 100644 index c1ff03481a..0000000000 --- a/code_samples/search/elasticsearch/config/aggregation_services.yaml +++ /dev/null @@ -1,10 +0,0 @@ -services: - App\Query\Aggregation\Elasticsearch\PriorityAggregationVisitor: - tags: - - { name: ibexa.search.elasticsearch.query.location.aggregation.visitor } - - { name: ibexa.search.elasticsearch.query.content.aggregation.visitor } - - App\Query\Aggregation\Elasticsearch\PriorityAggregationResultExtractor: - tags: - - { name: ibexa.search.elasticsearch.query.location.aggregation.result.extractor } - - { name: ibexa.search.elasticsearch.query.content.aggregation.result.extractor } diff --git a/code_samples/search/elasticsearch/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregation.php b/code_samples/search/elasticsearch/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregation.php deleted file mode 100644 index 986b86e09c..0000000000 --- a/code_samples/search/elasticsearch/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregation.php +++ /dev/null @@ -1,12 +0,0 @@ - Date: Sat, 11 Jan 2025 11:47:29 +0000 Subject: [PATCH 02/31] PHP CS Fixes --- .../Elasticsearch/PriorityRangeAggregationVisitor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code_samples/search/custom/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregationVisitor.php b/code_samples/search/custom/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregationVisitor.php index 219a99ce69..36c5b2b800 100644 --- a/code_samples/search/custom/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregationVisitor.php +++ b/code_samples/search/custom/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregationVisitor.php @@ -17,7 +17,7 @@ public function supports(Aggregation $aggregation, LanguageFilter $languageFilte } /** - * @param PriorityRangeAggregation $aggregation + * @param \App\Query\Aggregation\PriorityRangeAggregation $aggregation */ public function visit(AggregationVisitor $dispatcher, Aggregation $aggregation, LanguageFilter $languageFilter): array { From 30a915176f77f1702b304ebf033afbdf073356e6 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Sat, 11 Jan 2025 12:56:59 +0100 Subject: [PATCH 03/31] Update phpstan-baseline.neon --- phpstan-baseline.neon | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 6c7781a0be..d60ebb9c09 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -353,47 +353,47 @@ parameters: - message: "#^Method App\\\\Query\\\\Aggregation\\\\Elasticsearch\\\\PriorityAggregationResultExtractor\\:\\:extract\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" count: 1 - path: code_samples/search/elasticsearch/src/Query/Aggregation/Elasticsearch/PriorityAggregationResultExtractor.php + path: code_samples/search/custom/src/Query/Aggregation/Elasticsearch/PriorityAggregationResultExtractor.php - message: "#^Method App\\\\Query\\\\Criterion\\\\Elasticsearch\\\\CameraManufacturerVisitor\\:\\:visit\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 - path: code_samples/search/elasticsearch/src/Query/Criterion/Elasticsearch/CameraManufacturerVisitor.php + path: code_samples/search/custom/src/Query/Criterion/Elasticsearch/CameraManufacturerVisitor.php - message: "#^Method App\\\\Query\\\\SortClause\\\\Elasticsearch\\\\ScoreVisitor\\:\\:visit\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 - path: code_samples/search/elasticsearch/src/Query/SortClause/Elasticsearch/ScoreVisitor.php + path: code_samples/search/custom/src/Query/SortClause/Elasticsearch/ScoreVisitor.php - message: "#^Argument of an invalid type stdClass supplied for foreach, only iterables are supported\\.$#" count: 1 - path: code_samples/search/solr/src/Query/Aggregation/Solr/PriorityAggregationResultExtractor.php + path: code_samples/search/custom/src/Query/Aggregation/Solr/PriorityAggregationResultExtractor.php - message: "#^Method App\\\\Query\\\\Aggregation\\\\Solr\\\\PriorityAggregationResultExtractor\\:\\:canVisit\\(\\) has parameter \\$languageFilter with no value type specified in iterable type array\\.$#" count: 1 - path: code_samples/search/solr/src/Query/Aggregation/Solr/PriorityAggregationResultExtractor.php + path: code_samples/search/custom/src/Query/Aggregation/Solr/PriorityAggregationResultExtractor.php - message: "#^Method App\\\\Query\\\\Aggregation\\\\Solr\\\\PriorityAggregationResultExtractor\\:\\:extract\\(\\) has parameter \\$languageFilter with no value type specified in iterable type array\\.$#" count: 1 - path: code_samples/search/solr/src/Query/Aggregation/Solr/PriorityAggregationResultExtractor.php + path: code_samples/search/custom/src/Query/Aggregation/Solr/PriorityAggregationResultExtractor.php - message: "#^Method App\\\\Query\\\\Aggregation\\\\Solr\\\\PriorityRangeAggregationVisitor\\:\\:formatRangeValue\\(\\) has parameter \\$value with no type specified\\.$#" count: 1 - path: code_samples/search/solr/src/Query/Aggregation/Solr/PriorityRangeAggregationVisitor.php + path: code_samples/search/custom/src/Query/Aggregation/Solr/PriorityRangeAggregationVisitor.php - message: "#^Method App\\\\Query\\\\Aggregation\\\\Solr\\\\PriorityRangeAggregationVisitor\\:\\:visit\\(\\) should return array\\ but returns array\\\\>\\|string\\>\\.$#" count: 1 - path: code_samples/search/solr/src/Query/Aggregation/Solr/PriorityRangeAggregationVisitor.php + path: code_samples/search/custom/src/Query/Aggregation/Solr/PriorityRangeAggregationVisitor.php - message: "#^Parameter \\#2 \\$array of function array_map expects array, array\\\\|bool\\|float\\|int\\|string given\\.$#" count: 1 - path: code_samples/search/solr/src/Query/Criterion/Solr/CameraManufacturerVisitor.php + path: code_samples/search/custom/src/Query/Criterion/Solr/CameraManufacturerVisitor.php - message: "#^Call to an undefined method Ibexa\\\\FieldTypePage\\\\FieldType\\\\Page\\\\Block\\\\Renderer\\\\RenderRequestInterface\\:\\:getParameters\\(\\)\\.$#" From b7dd1665399d281504cb6a3cabda4f1449cc41fd Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Sat, 11 Jan 2025 13:38:07 +0100 Subject: [PATCH 04/31] Update phpstan-baseline.neon --- phpstan-baseline.neon | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index d60ebb9c09..bb6845f655 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -353,7 +353,7 @@ parameters: - message: "#^Method App\\\\Query\\\\Aggregation\\\\Elasticsearch\\\\PriorityAggregationResultExtractor\\:\\:extract\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" count: 1 - path: code_samples/search/custom/src/Query/Aggregation/Elasticsearch/PriorityAggregationResultExtractor.php + path: code_samples/search/custom/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregationResultExtractor.php - message: "#^Method App\\\\Query\\\\Criterion\\\\Elasticsearch\\\\CameraManufacturerVisitor\\:\\:visit\\(\\) return type has no value type specified in iterable type array\\.$#" @@ -368,17 +368,17 @@ parameters: - message: "#^Argument of an invalid type stdClass supplied for foreach, only iterables are supported\\.$#" count: 1 - path: code_samples/search/custom/src/Query/Aggregation/Solr/PriorityAggregationResultExtractor.php + path: code_samples/search/custom/src/Query/Aggregation/Solr/PriorityRangeAggregationResultExtractor.php - message: "#^Method App\\\\Query\\\\Aggregation\\\\Solr\\\\PriorityAggregationResultExtractor\\:\\:canVisit\\(\\) has parameter \\$languageFilter with no value type specified in iterable type array\\.$#" count: 1 - path: code_samples/search/custom/src/Query/Aggregation/Solr/PriorityAggregationResultExtractor.php + path: code_samples/search/custom/src/Query/Aggregation/Solr/PriorityRangeAggregationResultExtractor.php - message: "#^Method App\\\\Query\\\\Aggregation\\\\Solr\\\\PriorityAggregationResultExtractor\\:\\:extract\\(\\) has parameter \\$languageFilter with no value type specified in iterable type array\\.$#" count: 1 - path: code_samples/search/custom/src/Query/Aggregation/Solr/PriorityAggregationResultExtractor.php + path: code_samples/search/custom/src/Query/Aggregation/Solr/PriorityRangeAggregationResultExtractor.php - message: "#^Method App\\\\Query\\\\Aggregation\\\\Solr\\\\PriorityRangeAggregationVisitor\\:\\:formatRangeValue\\(\\) has parameter \\$value with no type specified\\.$#" From d44d436ae275da666bada0ce96d5add393fa5c67 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Sat, 11 Jan 2025 16:54:02 +0100 Subject: [PATCH 05/31] Update phpstan-baseline.neon --- phpstan-baseline.neon | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index bb6845f655..427c3cab5e 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -351,7 +351,7 @@ parameters: path: code_samples/page/page_listener/src/Block/Listener/MyBlockListener.php - - message: "#^Method App\\\\Query\\\\Aggregation\\\\Elasticsearch\\\\PriorityAggregationResultExtractor\\:\\:extract\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + message: "#^Method App\\\\Query\\\\Aggregation\\\\Elasticsearch\\\\PriorityRangeAggregationResultExtractor\\:\\:extract\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" count: 1 path: code_samples/search/custom/src/Query/Aggregation/Elasticsearch/PriorityRangeAggregationResultExtractor.php @@ -371,12 +371,12 @@ parameters: path: code_samples/search/custom/src/Query/Aggregation/Solr/PriorityRangeAggregationResultExtractor.php - - message: "#^Method App\\\\Query\\\\Aggregation\\\\Solr\\\\PriorityAggregationResultExtractor\\:\\:canVisit\\(\\) has parameter \\$languageFilter with no value type specified in iterable type array\\.$#" + message: "#^Method App\\\\Query\\\\Aggregation\\\\Solr\\\\PriorityRangeAggregationResultExtractor\\:\\:canVisit\\(\\) has parameter \\$languageFilter with no value type specified in iterable type array\\.$#" count: 1 path: code_samples/search/custom/src/Query/Aggregation/Solr/PriorityRangeAggregationResultExtractor.php - - message: "#^Method App\\\\Query\\\\Aggregation\\\\Solr\\\\PriorityAggregationResultExtractor\\:\\:extract\\(\\) has parameter \\$languageFilter with no value type specified in iterable type array\\.$#" + message: "#^Method App\\\\Query\\\\Aggregation\\\\Solr\\\\PriorityRangeAggregationResultExtractor\\:\\:extract\\(\\) has parameter \\$languageFilter with no value type specified in iterable type array\\.$#" count: 1 path: code_samples/search/custom/src/Query/Aggregation/Solr/PriorityRangeAggregationResultExtractor.php From ec0c31f60e174717d10928a74247e1719b812821 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Sun, 12 Jan 2025 14:24:02 +0100 Subject: [PATCH 06/31] aggregation_services.yaml: Fix base visitor classes --- code_samples/search/custom/config/aggregation_services.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code_samples/search/custom/config/aggregation_services.yaml b/code_samples/search/custom/config/aggregation_services.yaml index 6653219743..939cc29bf2 100644 --- a/code_samples/search/custom/config/aggregation_services.yaml +++ b/code_samples/search/custom/config/aggregation_services.yaml @@ -1,6 +1,6 @@ services: app.search.solr.query.aggregation_visitor.priority_range_aggregation: - class: Ibexa\Solr\Query\Common\AggregationVisitor\PriorityRangeAggregationVisitor + class: Ibexa\Solr\Query\Common\AggregationVisitor\RangeAggregationVisitor factory: [ '@Ibexa\Solr\Query\Common\AggregationVisitor\Factory\ContentFieldAggregationVisitorFactory', 'createRangeAggregationVisitor' ] arguments: $aggregationClass: 'App\Query\Aggregation\Solr\PriorityRangeAggregation' @@ -10,7 +10,7 @@ services: - { name: ibexa.search.solr.query.location.aggregation.visitor } app.search.elasticsearch.query.aggregation_visitor.priority_range_aggregation: - class: Ibexa\Elasticsearch\Query\AggregationVisitor\PriorityRangeAggregationVisitor + class: Ibexa\Elasticsearch\Query\AggregationVisitor\RangeAggregationVisitor factory: [ '@Ibexa\Elasticsearch\Query\AggregationVisitor\Factory\SearchFieldAggregationVisitorFactory', 'createRangeAggregationVisitor' ] arguments: $aggregationClass: 'App\Query\Aggregation\Elasticsearch\PriorityRangeAggregation' From cedc24547f6de813fe391c78eadc798f3a587d61 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 13 Jan 2025 13:09:18 +0100 Subject: [PATCH 07/31] aggregation_services.yaml: Fix priority_range_aggregation factory --- code_samples/search/custom/config/aggregation_services.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code_samples/search/custom/config/aggregation_services.yaml b/code_samples/search/custom/config/aggregation_services.yaml index 939cc29bf2..2bc8f6ca0e 100644 --- a/code_samples/search/custom/config/aggregation_services.yaml +++ b/code_samples/search/custom/config/aggregation_services.yaml @@ -1,7 +1,7 @@ services: app.search.solr.query.aggregation_visitor.priority_range_aggregation: class: Ibexa\Solr\Query\Common\AggregationVisitor\RangeAggregationVisitor - factory: [ '@Ibexa\Solr\Query\Common\AggregationVisitor\Factory\ContentFieldAggregationVisitorFactory', 'createRangeAggregationVisitor' ] + factory: [ '@Ibexa\Solr\Query\Common\AggregationVisitor\Factory\SearchFieldAggregationVisitorFactory', 'createRangeAggregationVisitor' ] arguments: $aggregationClass: 'App\Query\Aggregation\Solr\PriorityRangeAggregation' $searchIndexFieldName: 'priority_i' From 497b24387713c34e2be49888b06bb449412c1704 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Fri, 7 Feb 2025 16:47:44 +0100 Subject: [PATCH 08/31] create_custom_search_criterion.md: Links to custom index pages --- .../search/extensibility/create_custom_search_criterion.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/search/extensibility/create_custom_search_criterion.md b/docs/search/extensibility/create_custom_search_criterion.md index 8d2babe9c9..eea7f735e8 100644 --- a/docs/search/extensibility/create_custom_search_criterion.md +++ b/docs/search/extensibility/create_custom_search_criterion.md @@ -39,7 +39,7 @@ Then, add a `CameraManufacturerVisitor` class, implementing `CriterionVisitor`: Finally, register the visitor as a service. Search Criteria can be valid for both Content and Location search. -To choose the search type, use either `content` or `location` in the tag when registering the visitor as a service:: +To choose the search type, use either `content` or `location` in the tag when registering the visitor as a service: === "Solr" @@ -54,3 +54,8 @@ To choose the search type, use either `content` or `location` in the tag when re services: [[= include_file('code_samples/search/custom/config/criterion_services.yaml', 6, 10) =]] ``` + +This example pretends a new `exif_camera_manufacturer_id` data is indexed. +For more information about indexing new additional data, +see [Solr document field mappers](solr_document_field_mappers.md) +or [Index custom Elasticsearch data](index_custom_elasticsearch_data.md). From 65ede71a20f5101743a3a66ac23a2531c0b2fe49 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Fri, 7 Feb 2025 17:25:33 +0100 Subject: [PATCH 09/31] create_custom_aggregation.md: Add a class section Mimic criterion and sort clause pages' structure. --- docs/search/extensibility/create_custom_aggregation.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/search/extensibility/create_custom_aggregation.md b/docs/search/extensibility/create_custom_aggregation.md index 15ca629bc9..246233f6d3 100644 --- a/docs/search/extensibility/create_custom_aggregation.md +++ b/docs/search/extensibility/create_custom_aggregation.md @@ -4,6 +4,8 @@ description: Create custom Aggregation to use with Solr and Elasticsearch search # Create custom Aggregation +## Create aggregation class + To create a custom Aggregation, create an aggregation class. In the following example, an aggregation groups the location query results by the location priority: From e1621480159b174fa6fbe1db568daa4bc745cb34 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Fri, 7 Feb 2025 21:50:28 +0100 Subject: [PATCH 10/31] create_custom_aggregation.md: Narrow usage to location priority_i is available only on locations *.query.content.* tags musn't be used with this example --- .../custom/config/aggregation_services.yaml | 8 --- .../create_custom_aggregation.md | 53 +++++++++++++------ 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/code_samples/search/custom/config/aggregation_services.yaml b/code_samples/search/custom/config/aggregation_services.yaml index 2bc8f6ca0e..ebfa0074f1 100644 --- a/code_samples/search/custom/config/aggregation_services.yaml +++ b/code_samples/search/custom/config/aggregation_services.yaml @@ -6,7 +6,6 @@ services: $aggregationClass: 'App\Query\Aggregation\Solr\PriorityRangeAggregation' $searchIndexFieldName: 'priority_i' tags: - - { name: ibexa.search.solr.query.content.aggregation.visitor } - { name: ibexa.search.solr.query.location.aggregation.visitor } app.search.elasticsearch.query.aggregation_visitor.priority_range_aggregation: @@ -17,7 +16,6 @@ services: $searchIndexFieldName: 'priority_i' tags: - { name: ibexa.search.elasticsearch.query.location.aggregation.visitor } - - { name: ibexa.search.elasticsearch.query.content.aggregation.visitor } app.search.solr.query.aggregation_result_extractor.priority_range_aggregation: class: Ibexa\Solr\ResultExtractor\AggregationResultExtractor\RangeAggregationResultExtractor @@ -26,7 +24,6 @@ services: $keyMapper: 'Ibexa\Solr\ResultExtractor\AggregationResultExtractor\RangeAggregationKeyMapper\IntRangeAggregationKeyMapper' tags: - { name: ibexa.search.solr.query.location.aggregation.result.extractor } - - { name: ibexa.search.solr.query.content.aggregation.result.extractor } app.search.elasticsearch.query.aggregation_result_extractor.priority_range_aggregation: class: Ibexa\Elasticsearch\Query\ResultExtractor\AggregationResultExtractor\RangeAggregationResultExtractor @@ -34,24 +31,19 @@ services: $aggregationClass: 'App\Query\Aggregation\Elasticsearch\PriorityRangeAggregation' tags: - { name: ibexa.search.elasticsearch.query.location.aggregation.result.extractor } - - { name: ibexa.search.elasticsearch.query.content.aggregation.result.extractor } App\Query\Aggregation\Solr\PriorityRangeAggregationVisitor: tags: - { name: ibexa.search.solr.query.location.aggregation.visitor } - - { name: ibexa.search.solr.query.content.aggregation.visitor } App\Query\Aggregation\Solr\PriorityRangeAggregationResultExtractor: tags: - { name: ibexa.search.solr.query.location.aggregation.result.extractor } - - { name: ibexa.search.solr.query.content.aggregation.result.extractor } App\Query\Aggregation\Elasticsearch\PriorityRangeAggregationVisitor: tags: - { name: ibexa.search.elasticsearch.query.location.aggregation.visitor } - - { name: ibexa.search.elasticsearch.query.content.aggregation.visitor } App\Query\Aggregation\Elasticsearch\PriorityRangeAggregationResultExtractor: tags: - { name: ibexa.search.elasticsearch.query.location.aggregation.result.extractor } - - { name: ibexa.search.elasticsearch.query.content.aggregation.result.extractor } diff --git a/docs/search/extensibility/create_custom_aggregation.md b/docs/search/extensibility/create_custom_aggregation.md index 246233f6d3..4c26426198 100644 --- a/docs/search/extensibility/create_custom_aggregation.md +++ b/docs/search/extensibility/create_custom_aggregation.md @@ -48,14 +48,14 @@ The example below uses `RangeAggregationVisitor`: ``` yaml services: - [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 1, 10) =]] + [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 1, 9) =]] ``` === "Elasticsearch" ``` yaml services: - [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 11, 20) =]] + [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 10, 18) =]] ``` The visitor is created by `SearchFieldAggregationVisitorFactory`. @@ -76,22 +76,20 @@ For the result extractor, you can use the built-in `RangeAggregationResultExtrac === "Solr" - Tag the service with `ibexa.search.solr.query.location.aggregation.result.extractor` - and `ibexa.search.solr.query.content.aggregation.result.extractor`. + Tag the service with `ibexa.search.solr.query.location.aggregation.result.extractor`. ``` yaml services: - [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 21, 29) =]] + [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 19, 26) =]] ``` === "Elasticsearch" - Tag the service with `ibexa.search.elasticsearch.query.location.aggregation.result.extractor` - and `ibexa.search.elasticsearch.query.content.aggregation.result.extractor`. + Tag the service with `ibexa.search.elasticsearch.query.location.aggregation.result.extractor`. ``` yaml services: - [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 30, 37) =]] + [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 27, 33) =]] ``` You can use a different type of aggregation, followed by respective visitor and extractor classes: @@ -141,6 +139,31 @@ The `canVisit()` method checks whether the provided aggregation is of the suppor The `visit()` method returns an array of results. +Finally, register the aggregation visitor as a service. + +=== "Solr" + + Tag the aggregation visitor with `ibexa.search.solr.query.location.aggregation.visitor`: + + ``` yaml + services: + [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 34, 37) =]] + ``` + + For content-based aggregations, use the `ibexa.search.solr.query.content.aggregation.visitor` tag. + +=== "Elasticsearch" + + Tag the aggregation visitor with `ibexa.elasticsearch.query.location.aggregation_visitor`: + + ``` yaml + services: + [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 42, 45) =]] + ``` + + For content-based aggregations, use the `ibexa.search.elasticsearch.query.content.aggregation.visitor` tag. + + ### Create result extractor === "Solr" @@ -172,26 +195,26 @@ The `visit()` method returns an array of results. The `extract()` method converts the [raw data provided by the search engine](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html) to a `RangeAggregationResult` object. -Finally, register both the aggregation visitor and the result extractor as services. +Finally, register the result extractor as a service. === "Solr" - Tag the aggregation visitor with `ibexa.search.solr.query.location.aggregation.visitor` and the result extractor with `ibexa.search.solr.query.location.aggregation.result.extractor`: + Tag the result extractor with `ibexa.search.solr.query.location.aggregation.result.extractor`: ``` yaml services: - [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 38, 47) =]] + [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 38, 41) =]] ``` - For content-based aggregations, use the `ibexa.search.solr.query.content.aggregation.visitor` and `ibexa.search.solr.query.content.aggregation.result.extractor` tags respectively. + For content-based aggregations, use the `ibexa.search.solr.query.content.aggregation.result.extractor` tag. === "Elasticsearch" - Tag the aggregation visitor with `ibexa.elasticsearch.query.location.aggregation_visitor` and the result extractor with `ibexa.elasticsearch.query.location.aggregation_result_extractor`: + Tag the result extractor with `ibexa.elasticsearch.query.location.aggregation_result_extractor`: ``` yaml services: - [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 48, 57) =]] + [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 46, 49) =]] ``` - For content-based aggregations, use the `ibexa.search.elasticsearch.query.content.aggregation.visitor` and `ibexa.search.elasticsearch.query.content.aggregation.result.extractor` tags respectively. + For content-based aggregations, use the `ibexa.search.elasticsearch.query.content.aggregation.result.extractor` tag. From a8cd54e619467381e66b8cc26a25414d5358d2c6 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Fri, 7 Feb 2025 22:17:50 +0100 Subject: [PATCH 11/31] create_custom_aggregation.md: Introduce Solr's $keyMapper --- docs/search/extensibility/create_custom_aggregation.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/search/extensibility/create_custom_aggregation.md b/docs/search/extensibility/create_custom_aggregation.md index 4c26426198..0b6e0b37af 100644 --- a/docs/search/extensibility/create_custom_aggregation.md +++ b/docs/search/extensibility/create_custom_aggregation.md @@ -78,6 +78,9 @@ For the result extractor, you can use the built-in `RangeAggregationResultExtrac Tag the service with `ibexa.search.solr.query.location.aggregation.result.extractor`. + As `$keyMapper` to transform raw keys into more usable objects or scalar values, use `IntRangeAggregationKeyMapper` + or create your own implementing [`RangeAggregationKeyMapper`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Solr-ResultExtractor-AggregationResultExtractor-RangeAggregationKeyMapper.html). + ``` yaml services: [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 19, 26) =]] From e160ab1544fcd7e36e120209728561e45c0efc0c Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Fri, 7 Feb 2025 22:47:09 +0100 Subject: [PATCH 12/31] create_custom_aggregation.md: Sort aggregation types --- .../create_custom_aggregation.md | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/docs/search/extensibility/create_custom_aggregation.md b/docs/search/extensibility/create_custom_aggregation.md index 0b6e0b37af..f322674f18 100644 --- a/docs/search/extensibility/create_custom_aggregation.md +++ b/docs/search/extensibility/create_custom_aggregation.md @@ -99,20 +99,27 @@ You can use a different type of aggregation, followed by respective visitor and === "Solr" - - `Ibexa\Solr\Query\Common\AggregationVisitor\StatsAggregationVisitor` - - `Ibexa\Solr\Query\Common\AggregationVisitor\TermAggregationVisitor` - - `Ibexa\Solr\ResultExtractor\AggregationResultExtractor\StatsAggregationResultExtractor` - - `Ibexa\Solr\ResultExtractor\AggregationResultExtractor\TermAggregationResultExtractor` + - Range + - `Ibexa\Solr\Query\Common\AggregationVisitor\RangeAggregationVisitor` + - `Ibexa\Solr\ResultExtractor\AggregationResultExtractor\RangeAggregationResultExtractor` + - Stats (count, minimum, maximum, average, sum) + - `Ibexa\Solr\Query\Common\AggregationVisitor\StatsAggregationVisitor` + - `Ibexa\Solr\ResultExtractor\AggregationResultExtractor\StatsAggregationResultExtractor` + - Term + - `Ibexa\Solr\Query\Common\AggregationVisitor\TermAggregationVisitor` + - `Ibexa\Solr\ResultExtractor\AggregationResultExtractor\TermAggregationResultExtractor` === "Elasticsearch" - - `Ibexa\ElasticSearchEngine\Query\AggregationVisitor\RangeAggregationVisitor` - - `Ibexa\ElasticSearchEngine\Query\AggregationVisitor\StatsAggregationVisitor` - - `Ibexa\ElasticSearchEngine\Query\AggregationVisitor\TermAggregationVisitor` - - - `Ibexa\ElasticSearchEngine\Query\ResultExtractor\AggregationResultExtractor\RangeAggregationResultExtractor` - - `Ibexa\ElasticSearchEngine\Query\ResultExtractor\AggregationResultExtractor\StatsAggregationResultExtractor` - - `Ibexa\ElasticSearchEngine\Query\ResultExtractor\AggregationResultExtractor\TermAggregationResultExtractor` + - Range + - `Ibexa\ElasticSearchEngine\Query\AggregationVisitor\RangeAggregationVisitor` + - `Ibexa\ElasticSearchEngine\Query\ResultExtractor\AggregationResultExtractor\RangeAggregationResultExtractor` + - Stats (count, minimum, maximum, average, sum) + - `Ibexa\ElasticSearchEngine\Query\AggregationVisitor\StatsAggregationVisitor` + - `Ibexa\ElasticSearchEngine\Query\ResultExtractor\AggregationResultExtractor\StatsAggregationResultExtractor` + - Term + - `Ibexa\ElasticSearchEngine\Query\AggregationVisitor\TermAggregationVisitor` + - `Ibexa\ElasticSearchEngine\Query\ResultExtractor\AggregationResultExtractor\TermAggregationResultExtractor` In a more complex use case, you must create your own visitor and extractor. From 4df96004478f9f75bb60b7b08aec386fc226d62c Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Fri, 7 Feb 2025 23:49:32 +0100 Subject: [PATCH 13/31] create_custom_aggregation.md: Add links to PHP API Ref, Fix FQCN --- .../create_custom_aggregation.md | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/search/extensibility/create_custom_aggregation.md b/docs/search/extensibility/create_custom_aggregation.md index f322674f18..2908273657 100644 --- a/docs/search/extensibility/create_custom_aggregation.md +++ b/docs/search/extensibility/create_custom_aggregation.md @@ -18,17 +18,17 @@ code_samples/search/custom/src/Query/Aggregation/PriorityRangeAggregation.php The `PriorityRangeAggregation` class extends `AbstractRangeAggregation`. The name of the class indicates that it aggregates the results by using the Range aggregation. -An aggregation must implement the `Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation` interface or inherit one of following abstract classes: +An aggregation must implement the [`Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Core-Repository-Values-Content-Query-Aggregation.html) interface or inherit one of following abstract classes: -- `Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\AbstractRangeAggregation` -- `Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\AbstractStatsAggregation` -- `Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\AbstractTermAggregation` +- [`Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\AbstractRangeAggregation`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Core-Repository-Values-Content-Query-Aggregation-AbstractRangeAggregation.html) +- [`Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\AbstractStatsAggregation`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Core-Repository-Values-Content-Query-Aggregation-AbstractStatsAggregation.html) +- [`Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\AbstractTermAggregation`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Core-Repository-Values-Content-Query-Aggregation-AbstractTermAggregation.html) An aggregation can also implement one of the following interfaces: -- `Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\FieldAggregation`, based on content field -- `Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\LocationAggregation`, based on content location -- `Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\RawAggregation`, based on details of the index structure +- [`Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\FieldAggregation`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Core-Repository-Values-Content-Query-Aggregation-FieldAggregation.html), based on content field +- [`Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\LocationAggregation`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Core-Repository-Values-Content-Query-Aggregation-LocationAggregation.html), based on content location +- [`Ibexa\Contracts\Core\Repository\Values\Content\Query\Aggregation\RawAggregation`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Core-Repository-Values-Content-Query-Aggregation-RawAggregation.html), based on details of the index structure !!! note "Aggregation definition" @@ -86,6 +86,8 @@ For the result extractor, you can use the built-in `RangeAggregationResultExtrac [[= include_file('code_samples/search/custom/config/aggregation_services.yaml', 19, 26) =]] ``` + For other cases, a [`TermAggregationKeyMapper`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Solr-ResultExtractor-AggregationResultExtractor-TermAggregationKeyMapper.html) interface is also available. + === "Elasticsearch" Tag the service with `ibexa.search.elasticsearch.query.location.aggregation.result.extractor`. @@ -127,7 +129,7 @@ In a more complex use case, you must create your own visitor and extractor. === "Solr" - The aggregation visitor must implement `Ibexa\Contracts\Solr\Query\AggregationVisitor`: + The aggregation visitor must implement [`Ibexa\Contracts\Solr\Query\AggregationVisitor`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Solr-Query-AggregationVisitor.html): ``` php --8<-- @@ -137,7 +139,7 @@ In a more complex use case, you must create your own visitor and extractor. === "Elasticsearch" - The aggregation visitor must implement `Ibexa\Contracts\ElasticSearchEngine\Query\AggregationVisitor`: + The aggregation visitor must implement [`Ibexa\Contracts\ElasticSearchEngine\Query\AggregationVisitor`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Elasticsearch-Query-AggregationVisitor.html): ``` php --8<-- @@ -178,7 +180,7 @@ Finally, register the aggregation visitor as a service. === "Solr" - You must also create a result extractor, which implements `Ibexa\Solr\ResultExtractor\AggregationResultExtractor` that transforms raw aggregation results from Solr into `AggregationResult` objects: + You must also create a result extractor, which implements [`Ibexa\Contracts\Solr\ResultExtractor\AggregationResultExtractor`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Solr-ResultExtractor-AggregationResultExtractor.html) that transforms raw aggregation results from Solr into `AggregationResult` objects: ``` php --8<-- @@ -192,7 +194,7 @@ Finally, register the aggregation visitor as a service. === "Elasticsearch" - You must also create a result extractor, which implements `Ibexa\Contracts\ElasticSearchEngine\Query\AggregationResultExtractor` that transforms raw aggregation results from Elasticsearch into `AggregationResult` objects: + You must also create a result extractor, which implements [`Ibexa\Contracts\ElasticSearchEngine\Query\AggregationResultExtractor`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Elasticsearch-Query-AggregationResultExtractor.html) that transforms raw aggregation results from Elasticsearch into `AggregationResult` objects: ``` php --8<-- From bb2894c42c633a9a9dbee145d9f7b747d41d8fcd Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 10 Feb 2025 11:27:51 +0100 Subject: [PATCH 14/31] solr_document_field_mappers.md: Links to PHP API Ref --- .../solr_document_field_mappers.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/search/extensibility/solr_document_field_mappers.md b/docs/search/extensibility/solr_document_field_mappers.md index 78a00e68ab..582f29d9b0 100644 --- a/docs/search/extensibility/solr_document_field_mappers.md +++ b/docs/search/extensibility/solr_document_field_mappers.md @@ -29,15 +29,15 @@ You can create the field mapper class anywhere inside your bundle, as long as yo There are three different field mappers. Each mapper implements two methods, by the same name, but accepting different arguments: -- `ContentFieldMapper` - - `::accept(Content $content)` - - `::mapFields(Content $content)` -- `ContentTranslationFieldMapper` - - `::accept(Content $content, $languageCode)` - - `::mapFields(Content $content, $languageCode)` -- `LocationFieldMapper` - - `::accept(Location $content)` - - `::mapFields(Location $content)` +- [`ContentFieldMapper`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Solr-FieldMapper-ContentTranslationFieldMapper.html) + - [`::accept(Content $content)`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Solr-FieldMapper-ContentTranslationFieldMapper.html#method_accept) + - [`::mapFields(Content $content)`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Solr-FieldMapper-ContentTranslationFieldMapper.html#method_mapFields) +- [`ContentTranslationFieldMapper`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Solr-FieldMapper-ContentTranslationFieldMapper.html) + - [`::accept(Content $content, $languageCode)`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Solr-FieldMapper-ContentTranslationFieldMapper.html#method_accept) + - [`::mapFields(Content $content, $languageCode)`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Solr-FieldMapper-ContentTranslationFieldMapper.html#method_mapFields) +- [`LocationFieldMapper`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Solr-FieldMapper-LocationFieldMapper.html) + - [`::accept(Location $content)`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Solr-FieldMapper-LocationFieldMapper.html#method_accept) + - [`::mapFields(Location $content)`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Solr-FieldMapper-LocationFieldMapper.html#method_mapFields) Mappers can be used on the extension points by registering them with the [service container](php_api.md#service-container) by using service tags, as follows: From 5bab11a2ec7a93777ec81e3e5bd7a64bdf041224 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 10 Feb 2025 12:02:01 +0100 Subject: [PATCH 15/31] index_custom_elasticsearch_data.md: Links to PHP API Ref --- docs/search/extensibility/index_custom_elasticsearch_data.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/search/extensibility/index_custom_elasticsearch_data.md b/docs/search/extensibility/index_custom_elasticsearch_data.md index 053f4c84e0..078019826f 100644 --- a/docs/search/extensibility/index_custom_elasticsearch_data.md +++ b/docs/search/extensibility/index_custom_elasticsearch_data.md @@ -9,8 +9,8 @@ Besides what is indexed automatically, you can add additional data to the Elasti To do so, subscribe to one of the following events: -- `Ibexa\Contracts\ElasticSearchEngine\Mapping\Event\ContentIndexCreateEvent` -- `Ibexa\Contracts\ElasticSearchEngine\Mapping\Event\LocationIndexCreateEvent` +- [`Ibexa\Contracts\ElasticSearchEngine\Mapping\Event\ContentIndexCreateEvent`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Elasticsearch-Mapping-Event-ContentIndexCreateEvent.html) +- [`Ibexa\Contracts\ElasticSearchEngine\Mapping\Event\LocationIndexCreateEvent`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Elasticsearch-Mapping-Event-LocationIndexCreateEvent.html) These events are called when the index is created for the content and location documents. From e5c950061c530b84cbe5b50ccfdb408efa6612d7 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 10 Feb 2025 12:08:08 +0100 Subject: [PATCH 16/31] index_custom_elasticsearch_data.md: Links to PHP API Ref --- docs/search/extensibility/index_custom_elasticsearch_data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/search/extensibility/index_custom_elasticsearch_data.md b/docs/search/extensibility/index_custom_elasticsearch_data.md index 078019826f..7214dd0585 100644 --- a/docs/search/extensibility/index_custom_elasticsearch_data.md +++ b/docs/search/extensibility/index_custom_elasticsearch_data.md @@ -16,7 +16,7 @@ These events are called when the index is created for the content and location d You can pass the event to a subscriber which gives you access to the document that you can modify. -In the following example, when an index in created for a content or a location document, the event subscriber adds a `custom_field` of the type `StringField` to the index: +In the following example, when an index in created for a content or a location document, the event subscriber adds a `custom_field` of the type [`StringField`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Core-Search-FieldType-StringField.html) to the index: ``` php hl_lines="19 20 21" Date: Mon, 10 Feb 2025 12:14:46 +0100 Subject: [PATCH 17/31] index_custom_elasticsearch_data.md: service registration is not mandatory --- docs/search/extensibility/index_custom_elasticsearch_data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/search/extensibility/index_custom_elasticsearch_data.md b/docs/search/extensibility/index_custom_elasticsearch_data.md index 7214dd0585..3b0dd7775b 100644 --- a/docs/search/extensibility/index_custom_elasticsearch_data.md +++ b/docs/search/extensibility/index_custom_elasticsearch_data.md @@ -63,7 +63,7 @@ final class CustomIndexDataSubscriber implements EventSubscriberInterface } ``` -Remember to register the subscriber as a service: +If your subscriber is not automatically properly configured, register it as a service: ``` yaml services: From 04c0c791db4cdf591d40601ffa391a09a7b49b43 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 10 Feb 2025 12:26:01 +0100 Subject: [PATCH 18/31] customize_elasticsearch_index_structure.md: Indicate CompositeGroupResolver as default Don't make the reader guess it from default strategy description, just label it. --- .../extensibility/customize_elasticsearch_index_structure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/search/extensibility/customize_elasticsearch_index_structure.md b/docs/search/extensibility/customize_elasticsearch_index_structure.md index d4abc3e97f..df85aa3c35 100644 --- a/docs/search/extensibility/customize_elasticsearch_index_structure.md +++ b/docs/search/extensibility/customize_elasticsearch_index_structure.md @@ -21,7 +21,7 @@ The strategies are: - `NullGroupResolver` - groups all documents into a single group. - `LanguageGroupResolver` - groups documents by language code. - `ContentTypeGroupResolver`- groups documents by content type ID. -- `CompositeGroupResolver` - allows combining multiple group resolves together to have a more granular index. +- `CompositeGroupResolver` - allows combining multiple group resolves together to have a more granular index (default). The default strategy is the composite of language and content type ID, resulting in indexes in the form of `___`. From 60188d9be078f0a35a69483242bca3c0984008fb Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 10 Feb 2025 14:42:21 +0100 Subject: [PATCH 19/31] manipulate_elasticsearch_query.md: Link to PHP API Ref --- docs/search/extensibility/manipulate_elasticsearch_query.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/search/extensibility/manipulate_elasticsearch_query.md b/docs/search/extensibility/manipulate_elasticsearch_query.md index 98573ad949..94d4284ae8 100644 --- a/docs/search/extensibility/manipulate_elasticsearch_query.md +++ b/docs/search/extensibility/manipulate_elasticsearch_query.md @@ -5,7 +5,7 @@ description: Manipulate the search query when using the Elasticsearch search eng # Manipulate Elasticsearch query You can customize the search query before it's executed. -To do it, subscribe to `Ibexa\Contracts\ElasticSearchEngine\Query\Event\QueryFilterEvent`. +To do it, subscribe to [`Ibexa\Contracts\Elasticsearch\Query\Event\QueryFilterEvent`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Elasticsearch-Query-Event-QueryFilterEvent.html). The following example shows how to add an additional Search Criterion to all queries. From 474dd361de1abed4abf442b80d9ca760c6c4f790 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 10 Feb 2025 14:46:08 +0100 Subject: [PATCH 20/31] manipulate_elasticsearch_query.md: Fix redundancy --- docs/search/extensibility/manipulate_elasticsearch_query.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/search/extensibility/manipulate_elasticsearch_query.md b/docs/search/extensibility/manipulate_elasticsearch_query.md index 94d4284ae8..fac10e5051 100644 --- a/docs/search/extensibility/manipulate_elasticsearch_query.md +++ b/docs/search/extensibility/manipulate_elasticsearch_query.md @@ -7,7 +7,7 @@ description: Manipulate the search query when using the Elasticsearch search eng You can customize the search query before it's executed. To do it, subscribe to [`Ibexa\Contracts\Elasticsearch\Query\Event\QueryFilterEvent`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Elasticsearch-Query-Event-QueryFilterEvent.html). -The following example shows how to add an additional Search Criterion to all queries. +The following example shows how to add a Search Criterion to all queries. Depending on your configuration, this might impact all search queries, including those used for search and content tree in the back office. From 3f7c13c4d8bcc8a89c129500eda0d0c91a03d418 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 10 Feb 2025 15:06:03 +0100 Subject: [PATCH 21/31] manipulate_elasticsearch_query.md: service registration is not mandatory --- docs/search/extensibility/manipulate_elasticsearch_query.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/search/extensibility/manipulate_elasticsearch_query.md b/docs/search/extensibility/manipulate_elasticsearch_query.md index fac10e5051..eb48ada8a3 100644 --- a/docs/search/extensibility/manipulate_elasticsearch_query.md +++ b/docs/search/extensibility/manipulate_elasticsearch_query.md @@ -51,7 +51,7 @@ final class CustomQueryFilterSubscriber implements EventSubscriberInterface } ``` -Remember to register the subscriber as a service: +If your subscriber is not automatically properly configured, register it as a service: ``` yaml services: From ad59fb76985cfce60576691638a50ff8b5cd830a Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 10 Feb 2025 15:12:07 +0100 Subject: [PATCH 22/31] Move Elasticsearch subscribers to code_samples/ PHP files --- .../CustomIndexDataSubscriber.php | 42 +++++++++++++++++ .../CustomQueryFilterSubscriber.php | 37 +++++++++++++++ .../index_custom_elasticsearch_data.md | 45 ++----------------- .../manipulate_elasticsearch_query.md | 40 ++--------------- 4 files changed, 85 insertions(+), 79 deletions(-) create mode 100644 code_samples/search/custom/src/EventSubscriber/CustomIndexDataSubscriber.php create mode 100644 code_samples/search/custom/src/EventSubscriber/CustomQueryFilterSubscriber.php diff --git a/code_samples/search/custom/src/EventSubscriber/CustomIndexDataSubscriber.php b/code_samples/search/custom/src/EventSubscriber/CustomIndexDataSubscriber.php new file mode 100644 index 0000000000..28a7211d86 --- /dev/null +++ b/code_samples/search/custom/src/EventSubscriber/CustomIndexDataSubscriber.php @@ -0,0 +1,42 @@ +getDocument(); + $document->fields[] = new Field( + 'custom_field', + 'Custom field value', + new StringField() + ); + } + + public function onLocationDocumentCreate(LocationIndexCreateEvent $event): void + { + $document = $event->getDocument(); + $document->fields[] = new Field( + 'custom_field', + 'Custom field value', + new StringField() + ); + } + + public static function getSubscribedEvents(): array + { + return [ + ContentIndexCreateEvent::class => 'onContentDocumentCreate', + LocationIndexCreateEvent::class => 'onLocationDocumentCreate' + ]; + } +} diff --git a/code_samples/search/custom/src/EventSubscriber/CustomQueryFilterSubscriber.php b/code_samples/search/custom/src/EventSubscriber/CustomQueryFilterSubscriber.php new file mode 100644 index 0000000000..6037888685 --- /dev/null +++ b/code_samples/search/custom/src/EventSubscriber/CustomQueryFilterSubscriber.php @@ -0,0 +1,37 @@ +getQuery(); + + $additionalCriteria = new ObjectStateIdentifier('locked'); + + if ($query->filter !== null) { + $query->filter = $additionalCriteria; + } else { + // Append Criterion to existing filter + $query->filter = new LogicalAnd([ + $query->filter, + $additionalCriteria + ]); + } + } + + public static function getSubscribedEvents(): array + { + return [ + QueryFilterEvent::class => 'onQueryFilter' + ]; + } +} diff --git a/docs/search/extensibility/index_custom_elasticsearch_data.md b/docs/search/extensibility/index_custom_elasticsearch_data.md index 3b0dd7775b..70a7346572 100644 --- a/docs/search/extensibility/index_custom_elasticsearch_data.md +++ b/docs/search/extensibility/index_custom_elasticsearch_data.md @@ -19,48 +19,9 @@ You can pass the event to a subscriber which gives you access to the document th In the following example, when an index in created for a content or a location document, the event subscriber adds a `custom_field` of the type [`StringField`](../../api/php_api/php_api_reference/classes/Ibexa-Contracts-Core-Search-FieldType-StringField.html) to the index: ``` php hl_lines="19 20 21" -getDocument(); - $document->fields[] = new Field( - 'custom_field', - 'Custom field value', - new StringField() - ); - } - - public function onLocationDocumentCreate(LocationIndexCreateEvent $event): void - { - $document = $event->getDocument(); - $document->fields[] = new Field( - 'custom_field', - 'Custom field value', - new StringField() - ); - } - - public static function getSubscribedEvents(): array - { - return [ - ContentIndexCreateEvent::class => 'onContentDocumentCreate', - LocationIndexCreateEvent::class => 'onLocationDocumentCreate' - ]; - } -} +--8<-- +code_samples/search/custom/src/EventSubscriber/CustomIndexDataSubscriber.php +--8<-- ``` If your subscriber is not automatically properly configured, register it as a service: diff --git a/docs/search/extensibility/manipulate_elasticsearch_query.md b/docs/search/extensibility/manipulate_elasticsearch_query.md index eb48ada8a3..a1fbe5828a 100644 --- a/docs/search/extensibility/manipulate_elasticsearch_query.md +++ b/docs/search/extensibility/manipulate_elasticsearch_query.md @@ -12,43 +12,9 @@ The following example shows how to add a Search Criterion to all queries. Depending on your configuration, this might impact all search queries, including those used for search and content tree in the back office. ``` php hl_lines="34" -getQuery(); - - $additionalCriteria = new ObjectStateIdentifier('locked'); - - if ($query->filter !== null) { - $query->filter = $additionalCriteria; - } else { - // Append Criterion to existing filter - $query->filter = new LogicalAnd([ - $query->filter, - $additionalCriteria - ]); - } - } - - public static function getSubscribedEvents(): array - { - return [ - QueryFilterEvent::class => 'onQueryFilter' - ]; - } -} +--8<-- +code_samples/search/custom/src/EventSubscriber/CustomQueryFilterSubscriber.php +--8<-- ``` If your subscriber is not automatically properly configured, register it as a service: From e40ce7261248c616236fba9a3c04a8a7f981ab2f Mon Sep 17 00:00:00 2001 From: adriendupuis Date: Mon, 10 Feb 2025 14:57:25 +0000 Subject: [PATCH 23/31] PHP CS Fixes --- .../custom/src/EventSubscriber/CustomIndexDataSubscriber.php | 2 +- .../src/EventSubscriber/CustomQueryFilterSubscriber.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code_samples/search/custom/src/EventSubscriber/CustomIndexDataSubscriber.php b/code_samples/search/custom/src/EventSubscriber/CustomIndexDataSubscriber.php index 28a7211d86..02d216cdf0 100644 --- a/code_samples/search/custom/src/EventSubscriber/CustomIndexDataSubscriber.php +++ b/code_samples/search/custom/src/EventSubscriber/CustomIndexDataSubscriber.php @@ -36,7 +36,7 @@ public static function getSubscribedEvents(): array { return [ ContentIndexCreateEvent::class => 'onContentDocumentCreate', - LocationIndexCreateEvent::class => 'onLocationDocumentCreate' + LocationIndexCreateEvent::class => 'onLocationDocumentCreate', ]; } } diff --git a/code_samples/search/custom/src/EventSubscriber/CustomQueryFilterSubscriber.php b/code_samples/search/custom/src/EventSubscriber/CustomQueryFilterSubscriber.php index 6037888685..fbe91a3be3 100644 --- a/code_samples/search/custom/src/EventSubscriber/CustomQueryFilterSubscriber.php +++ b/code_samples/search/custom/src/EventSubscriber/CustomQueryFilterSubscriber.php @@ -23,7 +23,7 @@ public function onQueryFilter(QueryFilterEvent $event): void // Append Criterion to existing filter $query->filter = new LogicalAnd([ $query->filter, - $additionalCriteria + $additionalCriteria, ]); } } @@ -31,7 +31,7 @@ public function onQueryFilter(QueryFilterEvent $event): void public static function getSubscribedEvents(): array { return [ - QueryFilterEvent::class => 'onQueryFilter' + QueryFilterEvent::class => 'onQueryFilter', ]; } } From 43e98f84a07da5b006548da02c3a902a54283256 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 10 Feb 2025 16:27:22 +0100 Subject: [PATCH 24/31] build.yaml: Avoid too long code_samples_usage.diff.md --- .github/workflows/build.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 7bda6b4764..94bfa7960d 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -173,10 +173,15 @@ jobs: - name: Convert code_samples usages for comment if: steps.list.outputs.CODE_SAMPLES_CHANGE != '' && steps.diff.outputs.CODE_SAMPLES_DIFF != '0' run: | - echo '# code_samples/ change report' >> code_samples_usage.diff.md + echo '# code_samples/ change report' > code_samples_usage.diff.md echo '' >> code_samples_usage.diff.md php tools/code_samples/code_samples_usage_diff2html.php $HOME/code_samples_usage.diff >> code_samples_usage.diff.md echo 'Download colorized diff' >> code_samples_usage.diff.md + if [[ `wc -c < code_samples_usage.diff.md | xargs` -ge $((2**16)) ]]; then + echo '# code_samples/ change report' > code_samples_usage.diff.md + echo '' >> code_samples_usage.diff.md + echo 'Diff is too long to be displayed.' >> code_samples_usage.diff.md + fi - name: Find Comment id: find-comment uses: peter-evans/find-comment@v3 From 3433f9b05dd92a3c1d6ebe613e221f386a23616c Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 10 Feb 2025 17:50:14 +0100 Subject: [PATCH 25/31] build.yaml: Avoid too long code_samples_usage.diff.md --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4805117ce8..b38d2aae81 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -186,7 +186,7 @@ jobs: echo '' >> code_samples_usage.diff.md php tools/code_samples/code_samples_usage_diff2html.php $HOME/code_samples_usage.diff >> code_samples_usage.diff.md echo 'Download colorized diff' >> code_samples_usage.diff.md - if [[ `wc -c < code_samples_usage.diff.md | xargs` -ge $((2**16)) ]]; then + if [[ `wc -m < code_samples_usage.diff.md | xargs` -ge $((2**16)) ]]; then echo '# code_samples/ change report' > code_samples_usage.diff.md echo '' >> code_samples_usage.diff.md echo 'Diff is too long to be displayed.' >> code_samples_usage.diff.md From e15db119a3da6d2ae9b66eb848e08444fbd34fd6 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 10 Feb 2025 18:04:47 +0100 Subject: [PATCH 26/31] create_custom_aggregation.md: Explain why only location tag, fix tag. --- docs/search/extensibility/create_custom_aggregation.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/search/extensibility/create_custom_aggregation.md b/docs/search/extensibility/create_custom_aggregation.md index 2908273657..fb7ce9c0ed 100644 --- a/docs/search/extensibility/create_custom_aggregation.md +++ b/docs/search/extensibility/create_custom_aggregation.md @@ -64,13 +64,20 @@ You provide it with two arguments: - The aggregation class in `aggregationClass` - The field name in search index in `searchIndexFieldName` +In this example, the field is `priority_i` which exists only for locations. + === "Solr" Tag the service with `ibexa.search.solr.query.location.aggregation.visitor`. + For content-based aggregations, use the ibexa.search.solr.query.content.aggregation.visitor tag. + === "Elasticsearch" - Tag the service with `ibexa.elasticsearch.query.location.aggregation_visitor`. + Tag the service with `ibexa.search.elasticsearch.query.location.aggregation_visitor`. + + For content-based aggregations, use the ibexa.search.elasticsearch.query.content.aggregation.visitor tag. + For the result extractor, you can use the built-in `RangeAggregationResultExtractor` and provide it with the aggregation class in the `aggregationClass` parameter. From 2dbf67b0cc9f98c2fc30b02d1006138a561f976f Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Tue, 11 Feb 2025 09:31:36 +0100 Subject: [PATCH 27/31] build.yaml: Avoid too long code_samples_usage.diff.md --- .github/workflows/build.yaml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index b38d2aae81..3e0174177b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -182,14 +182,18 @@ jobs: - name: Convert code_samples usages for comment if: steps.list.outputs.CODE_SAMPLES_CHANGE != '' && steps.diff.outputs.CODE_SAMPLES_DIFF != '0' run: | - echo '# code_samples/ change report' > code_samples_usage.diff.md + title='# code_samples/ change report' + link='Download colorized diff' + echo $title > code_samples_usage.diff.md echo '' >> code_samples_usage.diff.md php tools/code_samples/code_samples_usage_diff2html.php $HOME/code_samples_usage.diff >> code_samples_usage.diff.md - echo 'Download colorized diff' >> code_samples_usage.diff.md + echo $link >> code_samples_usage.diff.md if [[ `wc -m < code_samples_usage.diff.md | xargs` -ge $((2**16)) ]]; then - echo '# code_samples/ change report' > code_samples_usage.diff.md + echo $title > code_samples_usage.diff.md echo '' >> code_samples_usage.diff.md - echo 'Diff is too long to be displayed.' >> code_samples_usage.diff.md + echo 'Report's diff is too long to be displayed in a comment.' >> code_samples_usage.diff.md + echo '' >> code_samples_usage.diff.md + echo $link >> code_samples_usage.diff.md fi - name: Find Comment id: find-comment From 5aef3cbf49dd3b35ec61736e30af0538f4f1cb04 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Tue, 11 Feb 2025 09:41:58 +0100 Subject: [PATCH 28/31] build.yaml: Avoid too long code_samples_usage.diff.md --- .github/workflows/build.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 3e0174177b..b67d915ca9 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -184,16 +184,16 @@ jobs: run: | title='# code_samples/ change report' link='Download colorized diff' - echo $title > code_samples_usage.diff.md + echo "$title" > code_samples_usage.diff.md echo '' >> code_samples_usage.diff.md php tools/code_samples/code_samples_usage_diff2html.php $HOME/code_samples_usage.diff >> code_samples_usage.diff.md - echo $link >> code_samples_usage.diff.md + echo "$link" >> code_samples_usage.diff.md if [[ `wc -m < code_samples_usage.diff.md | xargs` -ge $((2**16)) ]]; then - echo $title > code_samples_usage.diff.md + echo "$title" > code_samples_usage.diff.md echo '' >> code_samples_usage.diff.md echo 'Report's diff is too long to be displayed in a comment.' >> code_samples_usage.diff.md echo '' >> code_samples_usage.diff.md - echo $link >> code_samples_usage.diff.md + echo "$link" >> code_samples_usage.diff.md fi - name: Find Comment id: find-comment From 130f30b00ff47aac21c9a249a5018b12e0d2f4d4 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Tue, 11 Feb 2025 09:52:44 +0100 Subject: [PATCH 29/31] build.yaml: Avoid too long code_samples_usage.diff.md --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index b67d915ca9..b970075b85 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -191,7 +191,7 @@ jobs: if [[ `wc -m < code_samples_usage.diff.md | xargs` -ge $((2**16)) ]]; then echo "$title" > code_samples_usage.diff.md echo '' >> code_samples_usage.diff.md - echo 'Report's diff is too long to be displayed in a comment.' >> code_samples_usage.diff.md + echo "Report's diff is too long to be displayed in a comment." >> code_samples_usage.diff.md echo '' >> code_samples_usage.diff.md echo "$link" >> code_samples_usage.diff.md fi From 8159cde28a5b00dc2242e6d616c2dc0dd123c218 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:37:50 +0100 Subject: [PATCH 30/31] search/extensibility/*.md: Symfony's autoconfiguration --- docs/search/extensibility/index_custom_elasticsearch_data.md | 3 ++- docs/search/extensibility/manipulate_elasticsearch_query.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/search/extensibility/index_custom_elasticsearch_data.md b/docs/search/extensibility/index_custom_elasticsearch_data.md index 70a7346572..75a79ac137 100644 --- a/docs/search/extensibility/index_custom_elasticsearch_data.md +++ b/docs/search/extensibility/index_custom_elasticsearch_data.md @@ -24,7 +24,8 @@ code_samples/search/custom/src/EventSubscriber/CustomIndexDataSubscriber.php --8<-- ``` -If your subscriber is not automatically properly configured, register it as a service: +If you're not using [Symfony's autoconfiguration]([[= symfony_doc =]]/service_container.html#the-autoconfigure-option) +for event subscribers, register it as a service: ``` yaml services: diff --git a/docs/search/extensibility/manipulate_elasticsearch_query.md b/docs/search/extensibility/manipulate_elasticsearch_query.md index a1fbe5828a..d8f5cefa93 100644 --- a/docs/search/extensibility/manipulate_elasticsearch_query.md +++ b/docs/search/extensibility/manipulate_elasticsearch_query.md @@ -17,7 +17,8 @@ code_samples/search/custom/src/EventSubscriber/CustomQueryFilterSubscriber.php --8<-- ``` -If your subscriber is not automatically properly configured, register it as a service: +If you're not using [Symfony's autoconfiguration]([[= symfony_doc =]]/service_container.html#the-autoconfigure-option) +for event subscribers, register it as a service: ``` yaml services: From 8da31d0ca719c8f81cebc99d4b5ee7de62bc83f1 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:46:30 +0100 Subject: [PATCH 31/31] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marek NocoĊ„ --- docs/search/extensibility/create_custom_aggregation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/search/extensibility/create_custom_aggregation.md b/docs/search/extensibility/create_custom_aggregation.md index fb7ce9c0ed..b89d82443c 100644 --- a/docs/search/extensibility/create_custom_aggregation.md +++ b/docs/search/extensibility/create_custom_aggregation.md @@ -70,13 +70,13 @@ In this example, the field is `priority_i` which exists only for locations. Tag the service with `ibexa.search.solr.query.location.aggregation.visitor`. - For content-based aggregations, use the ibexa.search.solr.query.content.aggregation.visitor tag. + For content-based aggregations, use the `ibexa.search.solr.query.content.aggregation.visitor` tag. === "Elasticsearch" Tag the service with `ibexa.search.elasticsearch.query.location.aggregation_visitor`. - For content-based aggregations, use the ibexa.search.elasticsearch.query.content.aggregation.visitor tag. + For content-based aggregations, use the `ibexa.search.elasticsearch.query.content.aggregation.visitor` tag. For the result extractor, you can use the built-in `RangeAggregationResultExtractor` and provide it with the aggregation class in the `aggregationClass` parameter.