3

Is there a way to re-index all content for the core search engine?

In older versions, you could reindex with drush:

drush search-reindex --immediate --verbose

However, this does not appear to be an option anymore. In more recent versions of drush, one can do this:

drush search-api-reindex

However, that command is for the Search API module, and not for the core search index.

How do I re-index the core search index in bulk? Cron will only index up to 500 items at a time, but I have tens of thousands of items to index.

2 Answers 2

2

You can use the search index service directly

drush ev "\Drupal::service('search.index')->markForReindex();"

and then run drush cron as often as you need to.

In a Bash loop for example:

for (( c=1; c<=5; c++ )); do drush cron; done
12
  • This marks the items for re-indexing, but I don't think it re-indexes them. Is this any different than clicking the "Re-index site" button at admin/config/search/pages ?
    – arnoldbird
    Feb 13, 2022 at 15:41
  • This answer is about a scripting solution which replaces the no longer available single drush command with multiple ones to re-index in bulk. It's not about UI. Additionally the immediate option to run this in a single batch had its limitations. Even when the old command was still available re-indexing should have been run in batches to avoid time-outs and memory limits.
    – 4uk4
    Feb 13, 2022 at 16:56
  • If I run this markForReindex() function, and then run cron once, will this result in all content being indexed? It does not appear so. It appears to have the same effect as clicking the "Re-index site" button at admin/config/search/pages and then running cron. In other words, it will re-index one batch -- not all the content.
    – arnoldbird
    Feb 13, 2022 at 18:39
  • 1
    You don't have to wait for weeks, you can run drush cron in a loop back to back. Then it doesn't matter what batch size you have configured, the overhead for each batch run won't make much of a difference. If you don't want to run other cron-initiated processes you could invoke the search_cron() hook directly.
    – 4uk4
    Feb 13, 2022 at 20:09
  • 1
    Use a loop, I add an example.
    – 4uk4
    Feb 14, 2022 at 7:31
0

Here is some opinioned solution with automation based on @4uk4 answer.

remaining=$(drush ev "echo \Drupal::database()->query('SELECT COUNT(DISTINCT [n].[nid]) FROM {node} [n] LEFT JOIN {search_dataset} [sd] ON [sd].[sid] = [n].[nid] AND [sd].[type] = :type WHERE [sd].[sid] IS NULL OR [sd].[reindex] <> 0', [':type' => 'node'])->fetchField();"); \
size="$(drush cget search.settings index.cron_limit --format=string)"; \
iterations=$(( remaining/$size )); \
for (( c=1; c<=$iterations; c++ )); do printf "work on iteration $c/$iterations\n"; drush cron; done

In this "one line" script we get remaining items for indexing and calculate number of iterations. Then just running cron.

Note: remaining items query from the above is for nodes only.

BTW: you can control "Number of items to index per cron run" by drush config:set command.

Note: This script works well, but you will have to change this piece of code: [':type' => 'node'] to [':type' => 'node_search'] for Drupal 9.x

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.