Skip to content

Commit a93ef7b

Browse files
Merge pull request #363 from daniellienert/task/reduce-inner-loop
TASK: Reduce the dimensionCombinations for indexing
2 parents dd34d7a + 502d33b commit a93ef7b

6 files changed

Lines changed: 156 additions & 4 deletions

File tree

Classes/Indexer/NodeIndexer.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,15 @@ public function indexNode(NodeInterface $node, $targetWorkspaceName = null): voi
288288
};
289289

290290
$workspaceName = $targetWorkspaceName ?: $node->getContext()->getWorkspaceName();
291-
$handleNode($node, $this->createContentContext($workspaceName, $node->getDimensions()));
291+
$dimensionCombinations = $this->dimensionService->getDimensionCombinationsForIndexing($node);
292+
293+
if (array_filter($dimensionCombinations) === []) {
294+
$handleNode($node, $this->createContentContext($workspaceName));
295+
} else {
296+
foreach ($dimensionCombinations as $combination) {
297+
$handleNode($node, $this->createContentContext($workspaceName, $combination));
298+
}
299+
}
292300
}
293301

294302
/**

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)