Skip to content

Commit

Permalink
FEATURE: Add support for excluding NodeTypes from indexing
Browse files Browse the repository at this point in the history
Resolves: Flowpack#45
  • Loading branch information
r.michael@queo-group.com authored and r.michael@queo-group.com committed Jul 22, 2022
1 parent 5b62c98 commit 4a068d7
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 0 deletions.
20 changes: 20 additions & 0 deletions Classes/Indexer/NodeIndexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Flowpack\SimpleSearch\ContentRepositoryAdaptor\Indexer;

use Flowpack\SimpleSearch\ContentRepositoryAdaptor\Service\NodeTypeIndexingConfiguration;
use Flowpack\SimpleSearch\Domain\Service\IndexInterface;
use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\ContentRepository\Domain\Repository\WorkspaceRepository;
Expand All @@ -14,8 +15,10 @@
use Neos\ContentRepository\Search\Indexer\AbstractNodeIndexer;
use Neos\Eel\Exception;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Log\Utility\LogEnvironment;
use Neos\Flow\Persistence\PersistenceManagerInterface;
use Neos\Flow\Security\Context;
use Psr\Log\LoggerInterface;
use Symfony\Component\Yaml\Yaml;

/**
Expand Down Expand Up @@ -83,6 +86,18 @@ class NodeIndexer extends AbstractNodeIndexer
*/
protected $indexedNodeData = [];

/**
* @Flow\Inject
* @var NodeTypeIndexingConfiguration
*/
protected $nodeTypeIndexingConfiguration;

/**
* @Flow\Inject
* @var LoggerInterface
*/
protected $logger;

/**
* Called by the Flow object framework after creating the object and resolving all dependencies.
*
Expand Down Expand Up @@ -121,6 +136,11 @@ public function getIndexClient(): IndexInterface
*/
public function indexNode(NodeInterface $node, $targetWorkspaceName = null, $indexVariants = true): void
{
if ($this->nodeTypeIndexingConfiguration->isIndexable($node->getNodeType()) === false) {
$this->logger->debug(sprintf('Node "%s" (%s) skipped, Node Type is not allowed in the index.', $node->getContextPath(), $node->getNodeType()), LogEnvironment::fromMethodName(__METHOD__));
return;
}

if ($indexVariants === true) {
$this->indexAllNodeVariants($node);
return;
Expand Down
77 changes: 77 additions & 0 deletions Classes/Service/NodeTypeIndexingConfiguration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);

namespace Flowpack\SimpleSearch\ContentRepositoryAdaptor\Service;

/*
* This file is part of the Flowpack.ElasticSearch.ContentRepositoryAdaptor package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

use Neos\ContentRepository\Domain\Model\NodeType;
use Neos\ContentRepository\Domain\Service\NodeTypeManager;
use Neos\Flow\Annotations as Flow;

/**
* @Flow\Scope("singleton")
*/
final class NodeTypeIndexingConfiguration
{
/**
* @var array
* @Flow\InjectConfiguration(path="defaultConfigurationPerNodeType", package="Neos.ContentRepository.Search")
*/
protected $settings;

/**
* @Flow\Inject
* @var NodeTypeManager
*/
protected $nodeTypeManager;

/**
* @param NodeType $nodeType
* @return bool
*/
public function isIndexable(NodeType $nodeType): bool
{
if ($this->settings === null || !is_array($this->settings)) {
return true;
}

if (isset($this->settings[$nodeType->getName()]['indexed'])) {
return (bool)$this->settings[$nodeType->getName()]['indexed'];
}

$nodeTypeParts = explode(':', $nodeType->getName());
$namespace = reset($nodeTypeParts) . ':*';
if (isset($this->settings[$namespace]['indexed'])) {
return (bool)$this->settings[$namespace]['indexed'];
}
if (isset($this->settings['*']['indexed'])) {
return (bool)$this->settings['*']['indexed'];
}

return false;
}

/**
* @return array
* @throws Exception
*/
public function getIndexableConfiguration(): array
{
$nodeConfigurations = [];
/** @var NodeType $nodeType */
foreach ($this->nodeTypeManager->getNodeTypes(false) as $nodeType) {
$nodeConfigurations[$nodeType->getName()] = $this->isIndexable($nodeType);
}

return $nodeConfigurations;
}
}
7 changes: 7 additions & 0 deletions Configuration/Testing/NodeTypes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'Flowpack.SimpleSearch.ContentRepositoryAdaptor:BaseType':
superTypes: { }
'Flowpack.SimpleSearch.ContentRepositoryAdaptor:Type1':
superTypes:
'Flowpack.SimpleSearch.ContentRepositoryAdaptor:BaseType': true
'Flowpack.SimpleSearch.ContentRepositoryAdaptor:Type2':
superTypes: { }
11 changes: 11 additions & 0 deletions Configuration/Testing/Settings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Neos:
ContentRepository:
Search:
realtimeIndexing:
enabled: false
defaultConfigurationPerNodeType:
'*':
indexed: true
'Flowpack.SimpleSearch.ContentRepositoryAdaptor:Type1':
indexed: false

27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,30 @@ and configure the DB connection as needed:
value: '%env:DATABASE_PASSWORD%'

The `arguments` are the index identifier (can be chosen freely) and the DSN.

## Exclude NodeTypes from indexing

By default the indexing processes all NodeTypes, but you can change this in your *Settings.yaml*:

```yaml
Neos:
ContentRepository:
Search:
defaultConfigurationPerNodeType:
'*':
indexed: true
'Neos.Neos:FallbackNode':
indexed: false
'Neos.Neos:Shortcut':
indexed: false
'Neos.Neos:ContentCollection':
indexed: false
```
You need to explicitly configure the individual NodeTypes (this feature does not check the Super Type configuration).
But you can use a special notation to configure a full namespace, `Acme.AcmeCom:*` will be applied for all node
types in the `Acme.AcmeCom` namespace. The most specific configuration is used in this order:

- NodeType name (`Neos.Neos:Shortcut`)
- Full namespace notation (`Neos.Neos:*`)
- Catch all (`*`)
79 changes: 79 additions & 0 deletions Tests/Functional/Service/NodeTypeIndexingConfigurationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php
declare(strict_types=1);

namespace Flowpack\SimpleSearch\ContentRepositoryAdaptor\Tests\Functional\Service;

/*
* This file is part of the Flowpack.ElasticSearch.ContentRepositoryAdaptor package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

use Flowpack\SimpleSearch\ContentRepositoryAdaptor\Service\NodeTypeIndexingConfiguration;
use Neos\ContentRepository\Domain\Service\NodeTypeManager;
use Neos\Flow\Tests\FunctionalTestCase;

class NodeTypeIndexingConfigurationTest extends FunctionalTestCase
{

/**
* @var NodeTypeManager
*/
protected $nodeTypeManager;

/**
* @var NodeTypeIndexingConfiguration
*/
protected $nodeTypeIndexingConfiguration;

public function setUp(): void
{
parent::setUp();
$this->nodeTypeManager = $this->objectManager->get(NodeTypeManager::class);
$this->nodeTypeIndexingConfiguration = $this->objectManager->get(NodeTypeIndexingConfiguration::class);
}

public function nodeTypeDataProvider(): array
{
return [
'notIndexable' => [
'nodeTypeName' => 'Flowpack.SimpleSearch.ContentRepositoryAdaptor:Type1',
'expected' => false,
],
'indexable' => [
'nodeTypeName' => 'Flowpack.SimpleSearch.ContentRepositoryAdaptor:Type2',
'expected' => true,
],
];
}

/**
* @test
* @dataProvider nodeTypeDataProvider
*
* @param string $nodeTypeName
* @param bool $expected
* @throws \Neos\ContentRepository\Exception\NodeTypeNotFoundException
*/
public function isIndexable(string $nodeTypeName, bool $expected): void
{
self::assertEquals($expected, $this->nodeTypeIndexingConfiguration->isIndexable($this->nodeTypeManager->getNodeType($nodeTypeName)));
}

/**
* @test
* @dataProvider nodeTypeDataProvider
*
* @param string $nodeTypeName
* @param bool $expected
*/
public function getIndexableConfiguration(string $nodeTypeName, bool $expected): void
{
$indexableConfiguration = $this->nodeTypeIndexingConfiguration->getIndexableConfiguration();
self::assertEquals($indexableConfiguration[$nodeTypeName], $expected);
}
}

0 comments on commit 4a068d7

Please sign in to comment.