Today I learned how the indexer worked. I knew already, that while indexing in the backend you can decide which indexer not to run.

But what I didn’t know, it is the same on the CLI with dal:refresh:index
.
If you look into the cli command help we can check the options:
19:18:15 ~/var/www/current $ bin/console dal:refresh:index --help
Description:
Refreshes the index for a given entity
Usage:
dal:refresh:index [options]
Options:
--use-queue Ignore cache and force generation
--skip=SKIP Comma separated list of indexSo er names to be skipped
--only=ONLY Comma separated list of indexer names to be generated
-h, --help Display help for the given command. When no command is given display help for the list command
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi|--no-ansi Force (or disable --no-ansi) ANSI output
-n, --no-interaction Do not ask any interactive question
-e, --env=ENV The Environment name. [default: "prod"]
--no-debug Switch off debug mode.
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
We are interested in --only
and --skip
. What I wanted to do:
bin/console dal:refresh:index --only=product.search-keyword
I got the name of the indexer from the administration.
But nothing happend, so I dug into the code.
// \Shopware\Core\Framework\DataAbstractionLayer\Command\RefreshIndexCommand::execute protected function execute(InputInterface $input, OutputInterface $output): int { $this->io = new ShopwareStyle($input, $output); $skip = \is_string($input->getOption('skip')) ? explode(',', (string) $input->getOption('skip')) : []; $only = \is_string($input->getOption('only')) ? explode(',', (string) $input->getOption('only')) : []; $this->registry->index($input->getOption('use-queue'), $skip, $only); $skipEntities = array_map(fn ($indexer) => str_replace('.indexer', '', (string) $indexer), $skip); $onlyEntities = array_map(fn ($indexer) => str_replace('.indexer', '', (string) $indexer), $only); $event = new RefreshIndexEvent(!$input->getOption('use-queue'), $skipEntities, $onlyEntities); $this->eventDispatcher->dispatch($event); return self::SUCCESS; }
In the command implementation except that the indexer needs to be seperated by comma. For me, this was know, but hopefully you read the help text carefully.
So let’s look into the index method:
\Shopware\Core\Framework\DataAbstractionLayer\Indexing\EntityIndexerRegistry::index public function index(bool $useQueue, array $skip = [], array $only = []): void { foreach ($this->indexer as $indexer) { if (\in_array($indexer->getName(), $skip, true)) { continue; } if (\count($only) > 0 && !\in_array($indexer->getName(), $only, true)) { continue; } $offset = null; $this->dispatcher->dispatch(new ProgressStartedEvent($indexer->getName(), $indexer->getTotal())); while ($message = $indexer->iterate($offset)) { $message->setIndexer($indexer->getName()); $message->addSkip(...$skip); $this->sendOrHandle($message, $useQueue); $offset = $message->getOffset(); try { $count = \is_array($message->getData()) ? \count($message->getData()) : 1; $this->dispatcher->dispatch(new ProgressAdvancedEvent($count)); } catch (\Exception) { } } $this->dispatcher->dispatch(new ProgressFinishedEvent($indexer->getName())); } }
And this is interesting and is as on the administration. We can filter with only and skip by indexer – unfortunately product.search-keyword
is not an indexer in this sense. But a process? updater? Whatever we want to call it, we can only skip any but not limit it to one of the processes.
TL;DR – if you only want to reindex the search keywords, your cli command must look like this:
19:27:38 ~/var/www/current $ bin/console dal:refresh:index --use-queue --only=product.indexer --skip=product.inheritance,product.stock,product.variant-listing,product.child-count,product.many-to-many-id-field,product.category-denormalizer,product.cheapest-price,product.rating-averaget,product.stream,product.seo-url
We run only the product.indexer
and skip everything which is not the product.search-keyword
.
Aha finally some useful infos about this issue. Nobody once wrote down how the command should look like as a complete version. They could have used some examples when adding that function. So thank you for sharing!