Skip to content

Commit 502d33b

Browse files
committed
TASK: Reduce the dimensionCombinations for indexing
Instead of indexing all alloewd dimension combinations we now only index the dimensions of the current node and all dimensionCombinartions that fall back to that nodes dimensions.
1 parent 9d26a03 commit 502d33b

6 files changed

Lines changed: 148 additions & 11 deletions

File tree

Classes/Indexer/NodeIndexer.php

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
use Flowpack\ElasticSearch\Domain\Model\Index;
3232
use Flowpack\ElasticSearch\Transfer\Exception\ApiException;
3333
use Neos\ContentRepository\Domain\Model\NodeInterface;
34-
use Neos\ContentRepository\Domain\Service\ContentDimensionCombinator;
3534
use Neos\ContentRepository\Domain\Service\Context;
3635
use Neos\ContentRepository\Domain\Service\ContextFactory;
3736
use Neos\ContentRepository\Search\Indexer\AbstractNodeIndexer;
@@ -82,12 +81,6 @@ class NodeIndexer extends AbstractNodeIndexer implements BulkNodeIndexerInterfac
8281
*/
8382
protected $logger;
8483

85-
/**
86-
* @Flow\Inject
87-
* @var ContentDimensionCombinator
88-
*/
89-
protected $contentDimensionCombinator;
90-
9184
/**
9285
* @Flow\Inject
9386
* @var ContextFactory
@@ -295,7 +288,7 @@ public function indexNode(NodeInterface $node, $targetWorkspaceName = null): voi
295288
};
296289

297290
$workspaceName = $targetWorkspaceName ?: $node->getContext()->getWorkspaceName();
298-
$dimensionCombinations = $this->contentDimensionCombinator->getAllAllowedCombinations();
291+
$dimensionCombinations = $this->dimensionService->getDimensionCombinationsForIndexing($node);
299292

300293
if (array_filter($dimensionCombinations) === []) {
301294
$handleNode($node, $this->createContentContext($workspaceName));

Classes/Service/DimensionsService.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515

1616
use Neos\ContentRepository\Domain\Model\NodeInterface;
17+
use Neos\ContentRepository\Domain\Service\ContentDimensionCombinator;
1718
use Neos\ContentRepository\Utility;
1819
use Neos\Flow\Annotations as Flow;
1920

@@ -22,6 +23,12 @@
2223
*/
2324
class DimensionsService
2425
{
26+
/**
27+
* @Flow\Inject
28+
* @var ContentDimensionCombinator
29+
*/
30+
protected $contentDimensionCombinator;
31+
2532
/**
2633
* @var array
2734
*/
@@ -32,6 +39,11 @@ class DimensionsService
3239
*/
3340
protected $dimensionsRegistry = [];
3441

42+
/**
43+
* @var array
44+
*/
45+
protected $dimensionCombinationsForIndexing = [];
46+
3547
protected const HASH_DEFAULT = 'default';
3648

3749
/**
@@ -77,4 +89,40 @@ public function reset(): void
7789
$this->dimensionsRegistry = [];
7890
$this->lastTargetDimensions = null;
7991
}
92+
93+
/**
94+
* Only return the dimensions of the current node and all dimensions
95+
* that fall back to the current nodes dimensions.
96+
*
97+
* @param NodeInterface $node
98+
* @return array
99+
*/
100+
public function getDimensionCombinationsForIndexing(NodeInterface $node): array
101+
{
102+
$dimensionsHash = $this->hash($node->getDimensions());
103+
104+
if (!isset($this->dimensionCombinationsForIndexing[$dimensionsHash])) {
105+
$this->dimensionCombinationsForIndexing[$dimensionsHash] = $this->reduceDimensionCombinationstoSelfAndFallback(
106+
$this->contentDimensionCombinator->getAllAllowedCombinations(),
107+
$node->getDimensions()
108+
);
109+
}
110+
111+
return $this->dimensionCombinationsForIndexing[$dimensionsHash];
112+
}
113+
114+
protected function reduceDimensionCombinationstoSelfAndFallback(array $dimensionCombinations, array $nodeDimensions): array
115+
{
116+
return array_filter($dimensionCombinations, static function (array $dimensionCombination) use ($nodeDimensions) {
117+
foreach ($dimensionCombination as $dimensionKey => $dimensionValues) {
118+
if (!isset($nodeDimensions[$dimensionKey])) {
119+
return false;
120+
}
121+
if (empty(array_intersect($dimensionValues, $nodeDimensions[$dimensionKey]))) {
122+
return false;
123+
}
124+
}
125+
return true;
126+
});
127+
}
80128
}

Tests/Functional/Eel/ElasticSearchMultiDimensionQueryTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ public function countDkDimensionNodesTest(): void
9292
->sortDesc('title')
9393
->execute();
9494

95-
// expecting: root, document1, document2, document4 (fallback from de), untranslated (fallback from en_us) = 6
96-
static::assertCount(5, $resultDk->toArray());
97-
static::assertNodeNames(['root', 'document1', 'document2-dk', 'document4-de', 'document-untranslated'], $resultDk);
95+
// expecting: root, document1, document2, untranslated (fallback from en_us) = 4
96+
static::assertCount(4, $resultDk->toArray());
97+
static::assertNodeNames(['root', 'document1', 'document2-dk', 'document-untranslated'], $resultDk);
9898
}
9999
}

Tests/Functional/Traits/ContentRepositoryMultiDimensionNodeCreationTrait.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ protected function createNodesForNodeSearchTest(): void
7272
$documentNodeDe4 = $standaloneDocumentNode2De->createNode('document4-de', $this->nodeTypeManager->getNodeType('Flowpack.ElasticSearch.ContentRepositoryAdaptor:Document'));
7373
$documentNodeDe4->setProperty('title', 'document4-de');
7474

75+
// This one has no connetion to the DK root and DK does not fallback to DE, so this node should not be indexed!
7576
$translatedDocumentNode4Dk = $dkLanguageDimensionContext->adoptNode($documentNodeDe4, true);
7677
$translatedDocumentNode4Dk->setProperty('title', 'document4-dk');
7778

File renamed without changes.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Flowpack\ElasticSearch\ContentRepositoryAdaptor\Tests\Unit\Service;
5+
6+
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Indexer\NodeIndexer;
7+
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Service\DimensionsService;
8+
use Neos\Flow\Tests\UnitTestCase;
9+
10+
class DimensionServiceTest extends UnitTestCase
11+
{
12+
/**
13+
* @var DimensionsService
14+
*/
15+
protected $dimensionService;
16+
17+
public function setUp(): void
18+
{
19+
$proxyClass = $this->buildAccessibleProxy(DimensionsService::class);
20+
$this->dimensionService = new $proxyClass;
21+
}
22+
23+
public function dimensionCombinationProvider(): array
24+
{
25+
return [
26+
'multiDimension' => [
27+
'dimensionCombinations' => [
28+
[
29+
'country' => ['uk', 'us'],
30+
'language' => ['en_UK', 'en_US'],
31+
],
32+
[
33+
'country' => ['us'],
34+
'language' => ['en_US'],
35+
],
36+
[
37+
'country' => ['de'],
38+
'language' => ['de'],
39+
]
40+
],
41+
'nodeDimensions' => [
42+
'country' => ['us'],
43+
'language' => ['en_US'],
44+
],
45+
'expected' => [
46+
[
47+
'country' => ['uk', 'us'],
48+
'language' => ['en_UK', 'en_US'],
49+
],
50+
[
51+
'country' => ['us'],
52+
'language' => ['en_US'],
53+
]
54+
]
55+
],
56+
'singleDimension' => [
57+
'dimensionCombinations' => [
58+
[
59+
'language' => ['en_UK', 'en_US'],
60+
],
61+
[
62+
'language' => ['en_US'],
63+
],
64+
[
65+
'language' => ['de'],
66+
]
67+
],
68+
'nodeDimensions' => [
69+
'language' => ['en_US'],
70+
],
71+
'expected' => [
72+
[
73+
'language' => ['en_UK', 'en_US'],
74+
],
75+
[
76+
'language' => ['en_US'],
77+
]
78+
]
79+
]
80+
];
81+
}
82+
83+
/**
84+
* @test
85+
*
86+
* @dataProvider dimensionCombinationProvider
87+
* @param array $dimensionCombinations
88+
* @param array $nodeDimensions
89+
* @param array $expected
90+
*/
91+
public function reduceDimensionCombinationstoSelfAndFallback(array $dimensionCombinations, array $nodeDimensions, array $expected): void
92+
{
93+
self::assertEquals($expected, $this->dimensionService->_call('reduceDimensionCombinationstoSelfAndFallback', $dimensionCombinations, $nodeDimensions));
94+
}
95+
}

0 commit comments

Comments
 (0)