Skip to content

Commit 76d26a5

Browse files
committed
Merge pull request #33 from Flowpack/dimensions
[TASK] Dimensions support
2 parents a690b02 + 6a5814d commit 76d26a5

3 files changed

Lines changed: 129 additions & 15 deletions

File tree

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

Lines changed: 111 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ class NodeIndexCommandController extends CommandController {
3535
*/
3636
protected $nodeIndexingManager;
3737

38+
/**
39+
* @Flow\Inject
40+
* @var \TYPO3\TYPO3CR\Domain\Repository\WorkspaceRepository
41+
*/
42+
protected $workspaceRepository;
43+
3844
/**
3945
* @Flow\Inject
4046
* @var \TYPO3\TYPO3CR\Domain\Repository\NodeDataRepository
@@ -53,12 +59,33 @@ class NodeIndexCommandController extends CommandController {
5359
*/
5460
protected $contextFactory;
5561

62+
/**
63+
* @Flow\Inject
64+
* @var \TYPO3\Neos\Domain\Service\ContentDimensionPresetSourceInterface
65+
*/
66+
protected $contentDimensionPresetSource;
67+
5668
/**
5769
* @Flow\Inject
5870
* @var NodeTypeMappingBuilder
5971
*/
6072
protected $nodeTypeMappingBuilder;
6173

74+
/**
75+
* @var integer
76+
*/
77+
protected $indexedNodes;
78+
79+
/**
80+
* @var integer
81+
*/
82+
protected $countedIndexedNodes;
83+
84+
/**
85+
* @var integer
86+
*/
87+
protected $limit;
88+
6289
/**
6390
* @Flow\Inject
6491
* @var \Flowpack\ElasticSearch\ContentRepositoryAdaptor\LoggerInterface
@@ -106,9 +133,11 @@ public function showMappingCommand() {
106133
*
107134
* @param integer $limit Amount of nodes to index at maximum
108135
* @param bool $update if TRUE, do not throw away the index at the start. Should *only be used for development*.
136+
* @param string $workspace name of the workspace which should be indexed
109137
* @return void
110138
*/
111-
public function buildCommand($limit = NULL, $update = FALSE) {
139+
public function buildCommand($limit = NULL, $update = FALSE, $workspace = NULL) {
140+
112141
if ($update === TRUE) {
113142
$this->logger->log('!!! Update Mode (Development) active!', LOG_INFO);
114143
} else {
@@ -127,21 +156,19 @@ public function buildCommand($limit = NULL, $update = FALSE) {
127156
$this->logger->log(sprintf('Indexing %snodes ... ', ($limit !== NULL ? 'the first ' . $limit . ' ' : '')), LOG_INFO);
128157

129158
$count = 0;
130-
foreach ($this->nodeDataRepository->findAll() as $nodeData) {
131-
/** @var \TYPO3\TYPO3CR\Domain\Model\NodeData $nodeData */
132-
$context = $this->contextFactory->create(array(
133-
'workspaceName' => $nodeData->getWorkspace()->getName(),
134-
'invisibleContentShown' => TRUE,
135-
'removedContentShown' => TRUE,
136-
'inaccessibleContentShown' => TRUE
137-
));
138-
$node = $this->nodeFactory->createFromNodeData($nodeData, $context);
139-
if ($limit !== NULL && $count > $limit) {
140-
break;
159+
$this->limit = $limit;
160+
$this->indexedNodes = 0;
161+
$this->countedIndexedNodes = 0;
162+
163+
if ($workspace === NULL) {
164+
foreach ($this->workspaceRepository->findAll() as $workspace) {
165+
$this->indexWorkspace($workspace->getName());
166+
167+
$count = $count + $this->countedIndexedNodes;
141168
}
142-
$this->nodeIndexingManager->indexNode($node);
143-
$this->logger->log(sprintf(' %s', $node->getContextPath()), LOG_DEBUG);
144-
$count ++;
169+
} else {
170+
$this->indexWorkspace($workspace);
171+
$count = $count + $this->countedIndexedNodes;
145172
}
146173

147174
$this->nodeIndexingManager->flushQueues();
@@ -174,6 +201,75 @@ public function cleanupCommand() {
174201
$response = json_decode($exception->getResponse());
175202
$this->logger->log(sprintf('Nothing removed. ElasticSearch responded with status %s, saying "%s"', $response->status, $response->error));
176203
}
204+
}
205+
206+
/**
207+
* @param string $workspaceName
208+
*/
209+
protected function indexWorkspace($workspaceName) {
210+
211+
foreach ($this->calculateDimensionCombinations() as $combination) {
212+
$context = $this->contextFactory->create(array('workspaceName' => $workspaceName, 'dimensions' => $combination));
213+
$rootNode = $context->getRootNode();
214+
215+
$this->traverseNodes($rootNode);
216+
217+
$this->outputLine('Workspace "' . $workspaceName . '" and dimensions "' . json_encode($combination) . '" done. (Indexed ' . $this->indexedNodes . ' nodes)');
218+
$this->countedIndexedNodes = $this->countedIndexedNodes + $this->indexedNodes;
219+
$this->indexedNodes = 0;
220+
}
221+
}
222+
223+
/**
224+
* @param \TYPO3\TYPO3CR\Domain\Model\Node $currentNode
225+
*/
226+
protected function traverseNodes(\TYPO3\TYPO3CR\Domain\Model\Node $currentNode) {
227+
228+
if ($this->limit !== NULL && $this->indexedNodes > $this->limit) {
229+
return;
230+
}
231+
232+
$this->nodeIndexingManager->indexNode($currentNode);
233+
$this->indexedNodes++;
234+
235+
foreach ($currentNode->getChildNodes() as $childNode) {
236+
$this->traverseNodes($childNode);
237+
}
238+
}
239+
240+
/**
241+
* @return array
242+
* @todo will went into TYPO3CR
243+
*/
244+
protected function calculateDimensionCombinations() {
245+
$dimensionPresets = $this->contentDimensionPresetSource->getAllPresets();
246+
247+
$dimensionValueCountByDimension = array();
248+
$possibleCombinationCount = 1;
249+
$combinations = array();
250+
251+
foreach ($dimensionPresets as $dimensionName => $dimensionPreset) {
252+
if (isset($dimensionPreset['presets']) && !empty($dimensionPreset['presets'])) {
253+
$dimensionValueCountByDimension[$dimensionName] = count($dimensionPreset['presets']);
254+
$possibleCombinationCount = $possibleCombinationCount * $dimensionValueCountByDimension[$dimensionName];
255+
}
256+
}
257+
258+
foreach ($dimensionPresets as $dimensionName => $dimensionPreset) {
259+
for ($i = 0; $i < $possibleCombinationCount; $i++) {
260+
if (!isset($combinations[$i]) || !is_array($combinations[$i])) {
261+
$combinations[$i] = array();
262+
}
263+
264+
$currentDimensionCurrentPreset = current($dimensionPresets[$dimensionName]['presets']);
265+
$combinations[$i][$dimensionName] = $currentDimensionCurrentPreset['values'];
266+
267+
if (!next($dimensionPresets[$dimensionName]['presets'])) {
268+
reset($dimensionPresets[$dimensionName]['presets']);
269+
}
270+
}
271+
}
177272

273+
return $combinations;
178274
}
179275
}

Classes/Flowpack/ElasticSearch/ContentRepositoryAdaptor/Indexer/NodeIndexer.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,11 @@ public function getIndex() {
137137
*/
138138
public function indexNode(Node $node, $targetWorkspaceName = NULL) {
139139
$contextPath = $node->getContextPath();
140+
140141
if ($targetWorkspaceName !== NULL) {
141142
$contextPath = str_replace($node->getContext()->getWorkspace()->getName(), $targetWorkspaceName, $contextPath);
142143
}
144+
143145
$contextPathHash = sha1($contextPath);
144146
$nodeType = $node->getNodeType();
145147

@@ -169,6 +171,11 @@ public function indexNode(Node $node, $targetWorkspaceName = NULL) {
169171
$documentData['__workspace'] = $targetWorkspaceName;
170172
}
171173

174+
$dimensionCombinations = $node->getContext()->getDimensions();
175+
if (is_array($dimensionCombinations)) {
176+
$documentData['__dimensionCombinations'] = $dimensionCombinations;
177+
}
178+
172179
if ($this->isFulltextEnabled($node)) {
173180
if ($this->isFulltextRoot($node)) {
174181
// for fulltext root documents, we need to preserve the "__fulltext" field. That's why we use the

Classes/Flowpack/ElasticSearch/ContentRepositoryAdaptor/Mapping/NodeTypeMappingBuilder.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@ public function buildMappingInformation(Index $index) {
9292
$type = $index->findType(self::convertNodeTypeNameToMappingName($nodeTypeName));
9393
$mapping = new Mapping($type);
9494

95+
// http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-root-object-type.html#_dynamic_templates
96+
// 'not_analyzed' is necessary
97+
$mapping->addDynamicTemplate('dimensions', array(
98+
'path_match' => '__dimensionCombinations.*',
99+
'match_mapping_type' => 'string',
100+
'mapping' => array(
101+
'type' => 'string',
102+
'index' => 'not_analyzed'
103+
)
104+
));
105+
95106
foreach ($nodeType->getProperties() as $propertyName => $propertyConfiguration) {
96107
if (isset($propertyConfiguration['search']) && isset($propertyConfiguration['search']['elasticSearchMapping'])) {
97108

0 commit comments

Comments
 (0)