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

WIP ES document identifier: use node' identifier instead of path #11

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 3 additions & 6 deletions Classes/Driver/Version5/IndexerDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Driver\AbstractIndexerDriver;
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Driver\IndexerDriverInterface;
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Indexer\NodeIndexer;
use Flowpack\ElasticSearch\Domain\Model\Document as ElasticSearchDocument;
use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\Flow\Annotations as Flow;
Expand Down Expand Up @@ -88,11 +89,7 @@ public function fulltext(NodeInterface $node, array $fulltextIndexOfNode, string
return [];
}

$closestFulltextNodeContextPath = $closestFulltextNode->getContextPath();
if ($targetWorkspaceName !== null) {
$closestFulltextNodeContextPath = str_replace($node->getContext()->getWorkspace()->getName(), $targetWorkspaceName, $closestFulltextNodeContextPath);
}
$closestFulltextNodeDocumentIdentifier = sha1($closestFulltextNodeContextPath);
$closestFulltextNodeDocumentIdentifier = NodeIndexer::calculateDocumentIdentifier($closestFulltextNode);

if ($closestFulltextNode->isRemoved()) {
// fulltext root is removed, abort silently...
Expand All @@ -101,7 +98,7 @@ public function fulltext(NodeInterface $node, array $fulltextIndexOfNode, string
return [];
}

$this->logger->log(sprintf('NodeIndexer (%s): Updated fulltext index for %s (%s)', $closestFulltextNodeDocumentIdentifier, $closestFulltextNodeContextPath, $closestFulltextNode->getIdentifier()), LOG_DEBUG, null, 'ElasticSearch (CR)');
$this->logger->log(sprintf('NodeIndexer (%s): Updated fulltext index for %s (%s)', $closestFulltextNodeDocumentIdentifier, $closestFulltextNode->getPath(), $closestFulltextNode->getIdentifier()), LOG_DEBUG, null, 'ElasticSearch (CR)');

$upsertFulltextParts = [];
if (!empty($fulltextIndexOfNode)) {
Expand Down
49 changes: 42 additions & 7 deletions Classes/Indexer/NodeIndexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,35 @@ public function getIndex(): Index
return $index;
}

/**
* Something like getContextPath() but using the Node Identifier instead of the Path
*
* Result is a string like <identifier>@<workspace>;<dimensionsList>.
* @see NodeInterface::getContextPath()
*
* @param NodeInterface $node
* @return string
*/
protected static function getContextIdentifier(NodeInterface $node)
{
$contextIdentifier = $node->getIdentifier();

$context = $node->getContext();

$workspaceName = $context->getWorkspace()->getName();
$contextIdentifier .= '@' . $workspaceName;

if ($context->getDimensions() !== array()) {
$contextIdentifier .= ';';
foreach ($context->getDimensions() as $dimensionName => $dimensionValues) {
$contextIdentifier .= $dimensionName . '=' . implode(',', $dimensionValues) . '&';
}
$contextIdentifier = substr($contextIdentifier, 0, -1);
}

return $contextIdentifier;
}

/**
* Index this node, and add it to the current bulk request.
*
Expand Down Expand Up @@ -200,7 +229,7 @@ public function indexNode(NodeInterface $node, $targetWorkspaceName = null)
$contextPath = str_replace($node->getContext()->getWorkspace()->getName(), $targetWorkspaceName, $contextPath);
}

$documentIdentifier = $this->calculateDocumentIdentifier($node, $targetWorkspaceName);
$documentIdentifier = self::calculateDocumentIdentifier($node, $targetWorkspaceName);
$nodeType = $node->getNodeType();

$mappingType = $this->getIndex()->findType($this->nodeTypeMappingBuilder->convertNodeTypeNameToMappingName($nodeType->getName()));
Expand Down Expand Up @@ -243,9 +272,15 @@ public function indexNode(NodeInterface $node, $targetWorkspaceName = null)
$handleNode = function (NodeInterface $node, Context $context) use ($targetWorkspaceName, $indexer) {
$nodeFromContext = $context->getNodeByIdentifier($node->getIdentifier());
if ($nodeFromContext instanceof NodeInterface) {
if ($node->getPath() !== $nodeFromContext->getPath()) {
// If the node from context does have a different path, purge the context cache and re-fetch
// TODO: find the root cause for this bug and fix the node cache invalidation logic.
$context->getFirstLevelNodeCache()->flush();
$nodeFromContext = $context->getNodeByIdentifier($node->getIdentifier());
}
$indexer($nodeFromContext, $targetWorkspaceName);
} else {
$documentIdentifier = $this->calculateDocumentIdentifier($node, $targetWorkspaceName);
$documentIdentifier = self::calculateDocumentIdentifier($node, $targetWorkspaceName);
if ($node->isRemoved()) {
$this->removeNode($node, $context->getWorkspaceName());
$this->logger->log(sprintf('NodeIndexer (%s): Removed node with identifier %s, no longer in workspace %s', $documentIdentifier, $node->getIdentifier(), $context->getWorkspaceName()), LOG_DEBUG, null, 'ElasticSearch (CR)');
Expand Down Expand Up @@ -276,15 +311,15 @@ public function indexNode(NodeInterface $node, $targetWorkspaceName = null)
* @return string
* @throws \Neos\Flow\Persistence\Exception\IllegalObjectTypeException
*/
protected function calculateDocumentIdentifier(NodeInterface $node, $targetWorkspaceName = null): string
public static function calculateDocumentIdentifier(NodeInterface $node, $targetWorkspaceName = null): string
{
$contextPath = $node->getContextPath();
$contextIdentifier = self::getContextIdentifier($node);

if ($targetWorkspaceName !== null) {
$contextPath = str_replace($node->getContext()->getWorkspace()->getName(), $targetWorkspaceName, $contextPath);
$contextIdentifier = str_replace($node->getContext()->getWorkspace()->getName(), $targetWorkspaceName, $contextIdentifier);
}

return sha1($contextPath);
return sha1($contextIdentifier);
}

/**
Expand All @@ -310,7 +345,7 @@ public function removeNode(NodeInterface $node, string $targetWorkspaceName = nu
}
}

$documentIdentifier = $this->calculateDocumentIdentifier($node, $targetWorkspaceName);
$documentIdentifier = self::calculateDocumentIdentifier($node, $targetWorkspaceName);

$this->currentBulkRequest[] = $this->documentDriver->delete($node, $documentIdentifier);
$this->currentBulkRequest[] = $this->indexerDriver->fulltext($node, [], $targetWorkspaceName);
Expand Down