Programmatically update Search API index

Let's say that you use the Search API module and that you have SOLR and Database servers. One search index can use only one server at the time, so if something goes wrong with one of the servers and you have to switch to another server how would you do it if you had to write an update hook?

Both Server and Index are Config entities defined in the Search API module. You can see that here: Search API Entity

So, if we have a server called 'database_server' and an index called 'search_index' we can use the following code to change the server:

use Drupal\search_api\Entity\Index;
use Drupal\search_api\Entity\Server;

/**
 * Change search server to Database server.
 */
function MY_MODULE_update_8001() {
  $server = Server::load('database_server');
  $index = Index::load('search_index');
  $index->setServer($server);
  $index->save();
}

Make sure that your server is enabled before you attempt to switch to it. You can programmatically enable a server by adding this line:

$server->enable();

In some cases when we have simpler Config entities (like Block) that don't have much going on in their preSave() and postSave() methods, we can use the ConfigFactory to load a config item and set a new value. preSave() method in the Block class is only checking if the region is valid, and postSave() method is invalidating cache tags.

For example, to display a block title we could do this:

$block_config = \Drupal::configFactory()>getEditable('block.block.bartik_page_title');
$block_config->set('settings.label_display', 'visible');
$block_config->save();

But, using the ConfigFactory is not possible here, because the Index entity has a lot of interesting stuff in the preSave() and postSave() methods. We have to load the entity and then use appropriate methods.

About the Author

Goran Nikolovski is a web and AI developer with over 10 years of expertise in PHP, Drupal, Python, JavaScript, React, and React Native. He founded this website and enjoys sharing his knowledge.