Reindex only required indexers in Magento 2 from CLI

Don’t you just love it when you change some config option or switch to another branch or something similar and all of a sudden, a warning message pops up in Admin, saying:

One or more indexers are invalid. Make sure your Magento cron job is running.

Well, if you “love” it as much as I do, I’m going to show you how to address the particular indexer(s) without any hassle of knowing which one caused the warning to appear in the first place.

The following exa

mple deals with two arbitrary indexers on a project I am working on, but in reality code that will be presented in this article must work on any flagged indexer for indexation. Let’s jump to CLI and run the bin/magento indexer:status command and inspect the output:

+---------------------------------------+----------------------------------------------------+------------------+-----------+---------------------+---------------------+
| ID | Title | Status | Update On | Schedule Status | Schedule Updated |
+---------------------------------------+----------------------------------------------------+------------------+-----------+---------------------+---------------------+
| amasty_xsearch_category_fulltext | Amasty: Advanced Search - Categories | Ready | Schedule | idle (0 in backlog) | 2021-05-17 07:18:26 |
| amasty_elastic_relevance_rule_product | Amasty: ElasticSearch - Relevance Rules (Products) | Ready | Schedule | idle (0 in backlog) | 2021-05-17 07:18:31 |
| amasty_elastic_relevance_rule_rule | Amasty: ElasticSearch - Relevance Rules (Rules) | Ready | Schedule | idle (0 in backlog) | 2021-05-17 07:18:29 |
| amasty_elastic_popup_data | Amasty: Xsearch - Popup Data | Ready | Schedule | idle (0 in backlog) | 2021-05-17 07:18:31 |
| catalogrule_product | Catalog Product Rule | Ready | Schedule | idle (0 in backlog) | 2021-05-17 07:18:24 |
| catalogrule_rule | Catalog Rule Product | Ready | Schedule | idle (0 in backlog) | 2021-05-17 07:18:19 |
| catalogsearch_fulltext | Catalog Search | Reindex required | Schedule | idle (0 in backlog) | 2021-05-17 15:14:56 |
| catalog_category_flat | Category Flat Data | Ready | Schedule | idle (0 in backlog) | 2021-05-17 07:18:17 |
| catalog_category_product | Category Products | Reindex required | Schedule | idle (0 in backlog) | 2021-05-17 15:12:10 |
| customer_grid | Customer Grid | Ready | Schedule | idle (0 in backlog) | 2021-05-17 07:18:12 |
| design_config_grid | Design Config Grid | Ready | Schedule | idle (0 in backlog) | 2021-05-17 07:18:32 |
| catalog_product_category | Product Categories | Ready | Schedule | idle (0 in backlog) | 2021-05-17 15:12:10 |
| catalog_product_attribute | Product EAV | Ready | Schedule | idle (0 in backlog) | 2021-05-17 07:18:20 |
| catalog_product_flat | Product Flat Data | Ready | Schedule | idle (0 in backlog) | 2021-05-17 07:18:15 |
| catalog_product_price | Product Price | Ready | Schedule | idle (0 in backlog) | 2021-05-17 15:14:31 |
| cataloginventory_stock | Stock | Ready | Schedule | idle (0 in backlog) | 2021-05-17 15:14:33 |
+---------------------------------------+----------------------------------------------------+------------------+-----------+---------------------+---------------------+

In the following scenario you will notice there are two indexers that are flagged for indexing:

  • Catalog Search
  • Category Products

Now that we know which indexers became invalid, the only thing that needs to be done is to find a way to grab the indexer identifier (ID) which is used to run the individual indexer. Of course, without typing these values. Let’s start some bash programming!

Step 1 – grab the list of indexers that need to be run

The previous command needs to be connected to another one using pipe ‘|’, like so:

bin/magento indexer:status | grep required

The command does the following – take whatever output came from bin/magento indexer:status and use it to search for word required. Only if the results are found, it will be displayed back to CLI:

| catalogsearch_fulltext | Catalog Search | Reindex required | Schedule | idle (0 in backlog) | 2021-05-17 15:14:56 |
| catalog_category_product | Category Products | Reindex required | Schedule | idle (0 in backlog) | 2021-05-17 15:12:10 |

Step 2 – grab the ID value of an indexer

If you presumed you will use another pipe, you are correct. ๐Ÿ™‚ In the next part of command, we will split output result (string) into array using awk command using delimiter “|”.

bin/magento indexer:status | grep required | awk -F '|' '{print $2}'

As a result, you should get only the ID of the indexer, one per each row.

catalogsearch_fulltext
catalog_category_product

Step 3 – run the indexers only for the results ID(s)

This is the final step in which we need to take the output of the awk command and run the well known bin/magento indexer:reindex command:

bin/magento indexer:status | grep required | awk -F '|' '{print $2}' | xargs bin/magento indexer:reindex

Once executed in CLI, the following output should be returned to screen:

Category Products index has been rebuilt successfully in 00:00:15
Catalog Search has been rebuilt successfully in 00:00:13

Congratulations, you have successfully indexed whatever indexer was required to be reindexed! ๐Ÿ™‚

For those who want more

The final command from step 3 is somewhat short, but still quite long to remember and type each and every time you run into situation like this. That is why aliases come really handy, as they allow you to simplify big and juicy commands into something “human-friendly”, which will save you both time and effort.

Open your .bash_profile or .zshrc or any other config file for the terminal you are using and add the following:

alias m2rr="bin/magento indexer:status | grep required | awk -F '|' '{print $2}' | xargs bin/magento indexer:reindex"

After you save the file, it is important to the close currently opened terminal and open a new one in order for the new alias to be accessible. Now, if you type the command:

m2rr

the same command shown above will get executed. Neat, isn’t it? ๐Ÿ™‚

The alias should work on the following M2 versions:

  • 2.3.5 (thanks to Igor Perkusic for testing on his project)
  • 2.3.6
  • 2.4.2