Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NGSTACK-836: descendant indexing #9

Closed
wants to merge 64 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
047fd32
NGSTACK-836 parent child indexer
Mar 22, 2024
14a56dd
NGSTACK-836 remove SearchResultExtractorTrait from ParentChildFieldMa…
Mar 25, 2024
ad0b014
NGSTACK-836 remove argument from service definition
Mar 25, 2024
0aaa15b
NGSTACK-836 add parent child indexing compiler pass
Mar 25, 2024
a57942b
NGSTACK-836 service definition changes
Mar 28, 2024
94ebafb
NGSTACK-836 FulltextFieldResolver interface and remove search from Pa…
Mar 28, 2024
0d993e7
NGSTACK-836 use persistence location handler instead of location service
Mar 28, 2024
c778868
NGSTACK-836 add content id as key to parent ids property and unset pr…
Mar 28, 2024
6ef4212
NGSTACK-836 replace persistance handler with location handler, use in…
Mar 28, 2024
1523364
NGSTACK-836: use class constant instead of FQCN
pspanja May 29, 2024
8837723
NGSTACK-836: add strict types declaration and fix CS
pspanja May 29, 2024
169c715
NGSTACK-836: add property type annotation and fix CS
pspanja May 29, 2024
c0287a8
NGSTACK-836: fix CS
pspanja May 29, 2024
5ff522e
NGSTACK-836: fix CS
pspanja May 29, 2024
ccc7a7b
NGSTACK-836: remove unused imports
pspanja May 29, 2024
f05386f
NGSTACK-836: add strict types declaration and fix CS
pspanja May 29, 2024
b5456ed
NGSTACK-836: use getters instead of magic get and fix CS
pspanja May 29, 2024
6153cd0
NGSTACK-836: fix case mismatch
pspanja May 29, 2024
30b01aa
NGSTACK-836: clean up docblocks
pspanja May 29, 2024
05bcae0
NGSTACK-836: remove unnecessary type cast
pspanja May 29, 2024
3fb1559
NGSTACK-836: clean up docblocks
pspanja May 29, 2024
1e909d7
NGSTACK-836: fix CS
pspanja May 29, 2024
5c9d207
NGSTACK-836: fix spacing
pspanja May 29, 2024
a7e1cd6
NGSTACK-836: move configuration to the bottom
pspanja May 29, 2024
84608e7
NGSTACK-836: fix CS
pspanja May 29, 2024
3f8d403
NGSTACK-836: fix typo
pspanja May 29, 2024
a203e8b
NGSTACK-836: fix async indexing tests and prepare for testing parent-…
pspanja May 29, 2024
db33d05
NGSTACK-836: check and skip root Location
pspanja May 29, 2024
2cd560d
NGSTACK-836: handle exception when resolving content type identifier
pspanja May 29, 2024
4df4ff8
NGSTACK-836: restructure message handlers
pspanja May 29, 2024
ebafc0a
NGSTACK-836: restructure parent-child indexing field mapper
pspanja May 29, 2024
939f68a
NGSTACK-836: restructure parent-child indexing ancestor resolver
pspanja May 29, 2024
3039321
NGSTACK-836: fix test service configuration
pspanja May 29, 2024
23c12b6
NGSTACK-836: add parent-child indexing test for publishing version
pspanja May 29, 2024
ddf2565
NGSTACK-836: fix CS
pspanja May 31, 2024
369e106
NGSTACK-836: update test class name
pspanja May 31, 2024
6a8efc3
NGSTACK-836: rename parent-child indexing fulltext field mapper
pspanja May 31, 2024
15116cf
NGSTACK-836: make parent-child fulltext field mapper configurable
pspanja May 31, 2024
3860b3e
NGSTACK-836: implement recursive semantic config
pspanja Jun 3, 2024
107ec4c
NGSTACK-836: extract AncestorPathGenerator with test
pspanja Jun 4, 2024
bbd3d50
NGSTACK-836: fix indenting
pspanja Jun 6, 2024
ff7083d
NGSTACK-836: fix logged message
pspanja Jun 6, 2024
1dcf42d
NGSTACK-836: add AncestorResolver unit test
pspanja Jun 6, 2024
7b4bd61
NGSTACK-836: disable hierarchical indexing on legacy and asynchronous…
pspanja Jun 6, 2024
75d231f
NGSTACK-836: fix exclude configuration
pspanja Jun 6, 2024
f156dea
NGSTACK-836: fix service configuration
pspanja Jun 6, 2024
92682c8
NGSTACK-836: fix case mismatch
pspanja Jun 6, 2024
c14730b
NGSTACK-836: update for change in configuration
pspanja Jun 6, 2024
9980813
NGSTACK-836: implement configurable Solr field handlers for descendan…
pspanja Jun 7, 2024
88b873c
NGSTACK-836: rename parent child indexing to descendant indexing
pspanja Jun 10, 2024
e09c5d9
NGSTACK-836: rename parent child indexing to descendant indexing part 2
pspanja Jun 10, 2024
16c32fa
NGSTACK-836: add Block and BlockTranslation Descendant FieldMappers
pspanja Jun 11, 2024
8408d9f
NGSTACK-836: rename cleanup
pspanja Jun 11, 2024
6e5ab5c
NGSTACK-836: fix CS
pspanja Jun 11, 2024
1bd6ec2
NGSTACK-836 tests for descendant indexing
Jul 11, 2024
9a4a88a
NGSTACK-836 AncestorIndexer and AncestorResolver changes and swap loc…
Jul 11, 2024
f26849b
NGSTACK-836 remove unused qualifiers
Jul 11, 2024
4fa5771
NGSTACK-836 exclude descendant indexing tests (not supported with leg…
Jul 11, 2024
64247b5
NGSTACK-836 update tests throws tags
Jul 11, 2024
7dfbc42
NGSTACK-836 declare test return types
Jul 12, 2024
b6fc54a
NGSTACK-836 remove unnecessary code
Jul 12, 2024
57c186b
NGSTACK-836 renaming field mappers and custom solr fields
Jul 12, 2024
f18bea2
NGSTACK-836 fix handlers configuration
Jul 18, 2024
32a5b7a
NGSTACK-836 add documentation for descendant indexing
Jul 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 133 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:

jobs:
tests:
name: ${{ matrix.php }} ${{ matrix.coverage }} ${{ matrix.engine }} ${{ matrix.solr_version }} ${{ matrix.regression }} ${{ matrix.core_setup }}
name: ${{ matrix.php }} ${{ matrix.coverage }} ${{ matrix.engine }} ${{ matrix.solr_version }} ${{ matrix.regression }} ${{ matrix.asynchronous }} ${{ matrix.core_setup }}
runs-on: ubuntu-latest
env:
extensions: pdo_sqlite
Expand Down Expand Up @@ -53,6 +53,37 @@ jobs:
solr_cloud: 'yes'
core_setup: 'cloud'

- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-integration-solr-asynchronous.xml'
solr_version: '7.7.3'
solr_cores: 'collection1'
core_setup: 'single'
asynchronous: 'asynchronous'
- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-integration-solr-asynchronous.xml'
solr_version: '7.7.3'
core_setup: 'dedicated'
asynchronous: 'asynchronous'
- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-integration-solr-asynchronous.xml'
solr_version: '7.7.3'
core_setup: 'shared'
asynchronous: 'asynchronous'
- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-integration-solr-asynchronous.xml'
solr_version: '7.7.3'
solr_cloud: 'yes'
core_setup: 'cloud'
asynchronous: 'asynchronous'

- php: '8.1'
coverage: 'integration'
engine: 'solr'
Expand Down Expand Up @@ -84,6 +115,41 @@ jobs:
core_setup: 'cloud'
regression: 'regression'

- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-core-integration-legacy-solr-asynchronous.xml'
solr_version: '7.7.3'
solr_cores: 'collection1'
core_setup: 'single'
regression: 'regression'
asynchronous: 'asynchronous'
- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-core-integration-legacy-solr-asynchronous.xml'
solr_version: '7.7.3'
core_setup: 'dedicated'
regression: 'regression'
asynchronous: 'asynchronous'
- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-core-integration-legacy-solr-asynchronous.xml'
solr_version: '7.7.3'
core_setup: 'shared'
regression: 'regression'
asynchronous: 'asynchronous'
- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-core-integration-legacy-solr-asynchronous.xml'
solr_version: '7.7.3'
solr_cloud: 'yes'
core_setup: 'cloud'
regression: 'regression'
asynchronous: 'asynchronous'

- php: '8.1'
coverage: 'integration'
engine: 'solr'
Expand Down Expand Up @@ -111,6 +177,37 @@ jobs:
solr_cloud: 'yes'
core_setup: 'cloud'

- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-integration-solr-asynchronous.xml'
solr_version: '8.11.2'
solr_cores: 'collection1'
core_setup: 'single'
asynchronous: 'asynchronous'
- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-integration-solr-asynchronous.xml'
solr_version: '8.11.2'
core_setup: 'dedicated'
asynchronous: 'asynchronous'
- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-integration-solr-asynchronous.xml'
solr_version: '8.11.2'
core_setup: 'shared'
asynchronous: 'asynchronous'
- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-integration-solr-asynchronous.xml'
solr_version: '8.11.2'
solr_cloud: 'yes'
core_setup: 'cloud'
asynchronous: 'asynchronous'

- php: '8.1'
coverage: 'integration'
engine: 'solr'
Expand Down Expand Up @@ -142,6 +239,41 @@ jobs:
core_setup: 'cloud'
regression: 'regression'

- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-core-integration-legacy-solr-asynchronous.xml'
solr_version: '8.11.2'
solr_cores: 'collection1'
core_setup: 'single'
regression: 'regression'
asynchronous: 'asynchronous'
- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-core-integration-legacy-solr-asynchronous.xml'
solr_version: '8.11.2'
core_setup: 'dedicated'
regression: 'regression'
asynchronous: 'asynchronous'
- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-core-integration-legacy-solr-asynchronous.xml'
solr_version: '8.11.2'
core_setup: 'shared'
regression: 'regression'
asynchronous: 'asynchronous'
- php: '8.1'
coverage: 'integration'
engine: 'solr'
config: 'phpunit-core-integration-legacy-solr-asynchronous.xml'
solr_version: '8.11.2'
solr_cloud: 'yes'
core_setup: 'cloud'
regression: 'regression'
asynchronous: 'asynchronous'

steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
Expand Down
112 changes: 109 additions & 3 deletions bundle/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;

class Configuration implements ConfigurationInterface
{
Expand All @@ -25,6 +26,7 @@ public function getConfigTreeBuilder(): TreeBuilder
$this->addIndexableFieldTypeSection($rootNode);
$this->addSearchResultExtractorSection($rootNode);
$this->addAsynchronousIndexingSection($rootNode);
$this->addHierarchicalIndexingSection($rootNode);

return $treeBuilder;
}
Expand All @@ -45,7 +47,7 @@ private function addIndexableFieldTypeSection(ArrayNodeDefinition $nodeDefinitio
->info("Maximum number of characters for the indexed short text ('value' string type field)")
->defaultValue(256)
->end()
->end()
?->end()
->end()
->end()
->end()
Expand All @@ -60,7 +62,7 @@ private function addSearchResultExtractorSection(ArrayNodeDefinition $nodeDefini
->info('Get search result objects by loading them from the persistence layer, instead of reconstructing them from the returned Solr data')
->defaultTrue()
->end()
->end();
?->end();
}

private function addAsynchronousIndexingSection(ArrayNodeDefinition $nodeDefinition): void
Expand All @@ -71,6 +73,110 @@ private function addAsynchronousIndexingSection(ArrayNodeDefinition $nodeDefinit
->info('Use asynchronous mechanism to handle repository content indexing')
->defaultFalse()
->end()
->end();
?->end();
}

private function addHierarchicalIndexingSection(ArrayNodeDefinition $nodeDefinition): void
{
$childrenNodeDefinition = $nodeDefinition
->children()
->arrayNode('hierarchical_indexing')
->info('Hierarchical indexing configuration')
->addDefaultsIfNotSet()
->children()
->arrayNode('descendant_indexing')
->info('Descendant indexing configuration')
->addDefaultsIfNotSet()
->children()
->booleanNode('enabled')
->info('Enable/disable descendant indexing')
->defaultFalse()
->end()
?->arrayNode('map')
->useAttributeAsKey('name')
->normalizeKeys(false)
->arrayPrototype()
->children()
->arrayNode('handlers')
->info('List of indexing handlers to execute')
->example([
'handler_identifier_1',
'handler_identifier_2',
])
->scalarPrototype()
->defaultValue([])
->validate()
->ifTrue(fn ($v) => !is_string($v))
->thenInvalid('Handler identifier must be a string.')
->end()
->end()
?->end()
?->arrayNode('children')
->useAttributeAsKey('name')
->normalizeKeys(false)
->arrayPrototype()
;

$this->buildChildrenNode($childrenNodeDefinition);
}

private function evaluateChildren(&$child, $name): void
{
$builder = new TreeBuilder($name, 'array');
$root = $builder->getRootNode();

$this->buildChildrenNode($root);

$root->getNode(true)->finalize($child);
}

private function buildChildrenNode(ArrayNodeDefinition $node): void
{
$node
->addDefaultsIfNotSet()
->children()
->booleanNode('indexed')
->info('Whether the node should be indexed')
->defaultTrue()
->end()
?->variableNode('children')
->defaultValue([])
->validate()
->ifTrue(fn ($v) => !is_array($v))
->thenInvalid('The children element must be an array.')
->end()
->validate()
->always(
function ($children) {
array_walk($children, $this->evaluateChildren(...));

return $children;
}
)
->end()
->end()
?->end()
->validate()
->always(
function ($children) {
foreach (array_keys($children) as $key) {
$allowedOptions = ['indexed', 'children'];

if (!in_array($key, $allowedOptions, true)) {
throw new InvalidConfigurationException(
sprintf(
'Unrecognized option "%s". Available options are "%s".',
$key,
implode('", "', $allowedOptions),
),
);
}
}

return $children;
}
)
->end()
;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ private function processExtensionConfiguration(array $configs, ContainerBuilder
$this->processIndexableFieldTypeConfiguration($configuration, $container);
$this->processSearchResultExtractorConfiguration($configuration, $container);
$this->processAsynchronousIndexingConfiguration($configuration, $container);
$this->processDescendantIndexingConfiguration($configuration, $container);
}

private function processSearchResultExtractorConfiguration(array $configuration, ContainerBuilder $container): void
Expand Down Expand Up @@ -117,4 +118,12 @@ private function processAsynchronousIndexingConfiguration(array $configuration,
$configuration['use_asynchronous_indexing'],
);
}

private function processDescendantIndexingConfiguration(array $configuration, ContainerBuilder $container): void
{
$container->setParameter(
'netgen.ibexa_search_extra.descendant_indexing.configuration',
$configuration['hierarchical_indexing']['descendant_indexing'],
);
}
}
2 changes: 2 additions & 0 deletions bundle/NetgenIbexaSearchExtraBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Netgen\Bundle\IbexaSearchExtraBundle;

use Netgen\IbexaSearchExtra\Container\Compiler;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

Expand All @@ -21,6 +22,7 @@ public function build(ContainerBuilder $container): void
$container->addCompilerPass(new Compiler\AggregateFacetBuilderVisitorPass());
$container->addCompilerPass(new Compiler\AggregateSubdocumentQueryCriterionVisitorPass());
$container->addCompilerPass(new Compiler\AsynchronousIndexingPass());
$container->addCompilerPass(new Compiler\DescendantIndexingPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 100);
$container->addCompilerPass(new Compiler\FieldType\RichTextIndexablePass());
$container->addCompilerPass(new Compiler\SearchResultExtractorPass());
$container->addCompilerPass(new Compiler\RawFacetBuilderDomainVisitorPass());
Expand Down
Loading
Loading