Skip to content

Commit 15e1227

Browse files
committed
Merge pull request #108 from Flowpack/tast-better-dimensions
[TASK] Better support for Dimensions This change take care of Node variants in all dimension combinations during Indexing. This change introduce a new property in the Elasticsearch index called __dimensionCombinationHash so you need to reindex all your nodes.
2 parents aa93f19 + 3605673 commit 15e1227

8 files changed

Lines changed: 293 additions & 225 deletions

File tree

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ install:
2222
- cd neos-base-distribution
2323
script:
2424
- bin/phpunit -c Build/BuildEssentials/PhpUnit/UnitTests.xml Packages/Application/Flowpack.ElasticSearch.ContentRepositoryAdaptor/Tests/Unit
25-
- FLOW_CONTEXT=Testing/WithoutLanguageFallback bin/phpunit -c Build/BuildEssentials/PhpUnit/FunctionalTests.xml Packages/Application/Flowpack.ElasticSearch.ContentRepositoryAdaptor/Tests/Functional
25+
- bin/phpunit -c Build/BuildEssentials/PhpUnit/FunctionalTests.xml Packages/Application/Flowpack.ElasticSearch.ContentRepositoryAdaptor/Tests/Functional

Classes/Flowpack/ElasticSearch/ContentRepositoryAdaptor/Command/NodeIndexCommandController.php

Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use TYPO3\Flow\Annotations as Flow;
1515
use TYPO3\Flow\Cli\CommandController;
1616
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Mapping\NodeTypeMappingBuilder;
17+
use TYPO3\TYPO3CR\Domain\Service\ContentDimensionCombinator;
1718
use TYPO3\TYPO3CR\Search\Indexer\NodeIndexingManager;
1819

1920
/**
@@ -98,6 +99,12 @@ class NodeIndexCommandController extends CommandController
9899
*/
99100
protected $configurationManager;
100101

102+
/**
103+
* @Flow\Inject
104+
* @var ContentDimensionCombinator
105+
*/
106+
protected $contentDimensionCombinator;
107+
101108
/**
102109
* @var array
103110
*/
@@ -158,14 +165,19 @@ public function showMappingCommand()
158165
* @param integer $limit Amount of nodes to index at maximum
159166
* @param boolean $update if TRUE, do not throw away the index at the start. Should *only be used for development*.
160167
* @param string $workspace name of the workspace which should be indexed
168+
* @param string $postfix Index postfix, index with the same postifix will be deleted if exist
161169
* @return void
162170
*/
163-
public function buildCommand($limit = null, $update = false, $workspace = null)
171+
public function buildCommand($limit = null, $update = false, $workspace = null, $postfix = null)
164172
{
165173
if ($update === true) {
166174
$this->logger->log('!!! Update Mode (Development) active!', LOG_INFO);
167175
} else {
168-
$this->nodeIndexer->setIndexNamePostfix(time());
176+
$this->nodeIndexer->setIndexNamePostfix($postfix ?: time());
177+
if ($this->nodeIndexer->getIndex()->exists() === true) {
178+
$this->logger->log(sprintf('Deleted index with the same postfix (%s)!', $postfix), LOG_WARNING);
179+
$this->nodeIndexer->getIndex()->delete();
180+
}
169181
$this->nodeIndexer->getIndex()->create();
170182
$this->logger->log('Created index ' . $this->nodeIndexer->getIndexName(), LOG_INFO);
171183

@@ -238,7 +250,7 @@ public function cleanupCommand()
238250
*/
239251
protected function indexWorkspace($workspaceName)
240252
{
241-
$combinations = $this->calculateDimensionCombinations();
253+
$combinations = $this->contentDimensionCombinator->getAllAllowedCombinations();
242254
if ($combinations === array()) {
243255
$this->indexWorkspaceWithDimensions($workspaceName);
244256
} else {
@@ -287,41 +299,4 @@ protected function traverseNodes(\TYPO3\TYPO3CR\Domain\Model\NodeInterface $curr
287299
$this->traverseNodes($childNode);
288300
}
289301
}
290-
291-
/**
292-
* @return array
293-
* @todo will went into TYPO3CR
294-
*/
295-
protected function calculateDimensionCombinations()
296-
{
297-
$dimensionPresets = $this->contentDimensionPresetSource->getAllPresets();
298-
299-
$dimensionValueCountByDimension = array();
300-
$possibleCombinationCount = 1;
301-
$combinations = array();
302-
303-
foreach ($dimensionPresets as $dimensionName => $dimensionPreset) {
304-
if (isset($dimensionPreset['presets']) && !empty($dimensionPreset['presets'])) {
305-
$dimensionValueCountByDimension[$dimensionName] = count($dimensionPreset['presets']);
306-
$possibleCombinationCount = $possibleCombinationCount * $dimensionValueCountByDimension[$dimensionName];
307-
}
308-
}
309-
310-
foreach ($dimensionPresets as $dimensionName => $dimensionPreset) {
311-
for ($i = 0; $i < $possibleCombinationCount; $i++) {
312-
if (!isset($combinations[$i]) || !is_array($combinations[$i])) {
313-
$combinations[$i] = array();
314-
}
315-
316-
$currentDimensionCurrentPreset = current($dimensionPresets[$dimensionName]['presets']);
317-
$combinations[$i][$dimensionName] = $currentDimensionCurrentPreset['values'];
318-
319-
if (!next($dimensionPresets[$dimensionName]['presets'])) {
320-
reset($dimensionPresets[$dimensionName]['presets']);
321-
}
322-
}
323-
}
324-
325-
return $combinations;
326-
}
327302
}

Classes/Flowpack/ElasticSearch/ContentRepositoryAdaptor/Eel/ElasticSearchQueryBuilder.php

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -650,14 +650,13 @@ public function fetch()
650650
$this->result = $response->getTreatedContent();
651651

652652
$this->result['nodes'] = array();
653-
if (array_key_exists('hits', $this->result) && is_array($this->result['hits']) && count($this->result['hits']) > 0) {
654-
$this->result['nodes'] = $this->convertHitsToNodes($this->result['hits']);
655-
}
656-
657653
if ($this->logThisQuery === true) {
658654
$this->logger->log(sprintf('Query Log (%s): %s -- execution time: %s ms -- Limit: %s -- Number of results returned: %s -- Total Results: %s',
659655
$this->logMessage, json_encode($this->request), (($timeAfterwards - $timeBefore) * 1000), $this->limit, count($this->result['hits']['hits']), $this->result['hits']['total']), LOG_DEBUG);
660656
}
657+
if (array_key_exists('hits', $this->result) && is_array($this->result['hits']) && count($this->result['hits']) > 0) {
658+
$this->result['nodes'] = $this->convertHitsToNodes($this->result['hits']);
659+
}
661660

662661
return $this->result;
663662
}
@@ -699,7 +698,7 @@ public function count()
699698
$count = $treatedContent['count'];
700699

701700
if ($this->logThisQuery === true) {
702-
$this->logger->log('Query Log (' . $this->logMessage . '): ' . json_encode($this->request) . ' -- execution time: ' . (($timeAfterwards - $timeBefore) * 1000) . ' ms -- Total Results: ' . $count, LOG_DEBUG);
701+
$this->logger->log('Count Query Log (' . $this->logMessage . '): ' . json_encode($this->request) . ' -- execution time: ' . (($timeAfterwards - $timeBefore) * 1000) . ' ms -- Total Results: ' . $count, LOG_DEBUG);
703702
}
704703

705704
return $count;
@@ -773,8 +772,9 @@ public function query(NodeInterface $contextNode)
773772
$this->queryFilter('terms', array('__workspace' => array_unique(array('live', $contextNode->getContext()->getWorkspace()->getName()))));
774773

775774
// match exact dimension values for each dimension, this works because the indexing flattens the node variants for all dimension preset combinations
776-
foreach ($contextNode->getContext()->getDimensions() as $dimensionName => $dimensionValues) {
777-
$this->queryFilter('terms', array('__dimensionCombinations.' . $dimensionName => $dimensionValues, 'execution' => 'and'));
775+
$dimensionCombinations = $contextNode->getContext()->getDimensions();
776+
if (is_array($dimensionCombinations)) {
777+
$this->queryFilter('term', ['__dimensionCombinationHash' => md5(json_encode($dimensionCombinations))]);
778778
}
779779

780780
$this->contextNode = $contextNode;
@@ -817,15 +817,9 @@ protected function convertHitsToNodes(array $hits)
817817
* we might be able to use https://github.com/elasticsearch/elasticsearch/issues/3300 as soon as it is merged.
818818
*/
819819
foreach ($hits['hits'] as $hit) {
820-
// with ElasticSearch 1.0 fields always returns an array,
821-
// see https://github.com/Flowpack/Flowpack.ElasticSearch.ContentRepositoryAdaptor/issues/17
822-
if (is_array($hit['fields']['__path'])) {
823-
$nodePath = current($hit['fields']['__path']);
824-
} else {
825-
$nodePath = $hit['fields']['__path'];
826-
}
820+
$nodePath = current($hit['fields']['__path']);
827821
$node = $this->contextNode->getNode($nodePath);
828-
if ($node instanceof NodeInterface) {
822+
if ($node instanceof NodeInterface && !isset($nodes[$node->getIdentifier()])) {
829823
$nodes[$node->getIdentifier()] = $node;
830824
$elasticSearchHitPerNode[$node->getIdentifier()] = $hit;
831825
if ($this->limit > 0 && count($nodes) >= $this->limit) {
@@ -835,7 +829,7 @@ protected function convertHitsToNodes(array $hits)
835829
}
836830

837831
if ($this->logThisQuery === true) {
838-
$this->logger->log('Query Log (' . $this->logMessage . ') Number of returned results: ' . count($nodes), LOG_DEBUG);
832+
$this->logger->log('Returned nodes (' . $this->logMessage . '): ' . count($nodes), LOG_DEBUG);
839833
}
840834

841835
$this->elasticSearchHitsIndexedByNodeFromLastRequest = $elasticSearchHitPerNode;

0 commit comments

Comments
 (0)