Score:1

Edit index config (Search API) programmatically and get the status index updated

ru flag

I have a site with 14 pieces of news and 44 basic pages.

  1. I have created an index (Search API) with this bundle: enter image description here

and this is the index status (the content is already indexed during cron): enter image description here

  1. When I edit the config, add the Basic page bundle and save it: enter image description here

The index status is updated: enter image description here

I want to do the part 2 programmatically. I tried two ways:

$index = Index::load('my_index');
$index->setOption('datasource_settings', [
  'entity:node' => [
    'bundles' => [
      'default' => 0,
      'selected' => ['news', 'page'],
      'languages' => [
        'default' => 1',
        'selected' => [ ],
      ],
    ]
  ],
]);
$index->save();

and

$datasource_settings = [
  'entity:node' => [
    'bundles' => [
      'default' => 0,
      'selected' => ['news', 'page'],
      'languages' => [
        'default' => 'TRUE',
        'selected' => [ ],
      ],
    ]
  ],
];
$search_index = \Drupal::configFactory()->getEditable('search_api.index.my_index');
$search_index->set('datasource_settings', $datasource_settings)->save();

The config is saved, but the status index is not updated: enter image description here

I tried to use these codes:

Option 1:

$index = Index::load('my_index');
$index->reindex();

But the nodes number are not updated, and I lose the nodes indexed: enter image description here

Option 2:

$index = Index::load('my_index');
$index->rebuildTracker();

Result: enter image description here

Option 3:

$index = Index::load('my_index');
$index->clear();

Result: enter image description here

So my question is: How to update an index config programmatically and get the index status updated like the UI does when you click the Save button. I tried to look inside the search_api module code, but I got lost :(

Thank you in advance.

unusedspoon avatar
aq flag
As the search index is a config item you could try updating the config for it programatically https://www.drupal.org/docs/drupal-apis/update-api/updating-configuration-in-drupal-8
rpayanm avatar
ru flag
@unusedspoon I tried it like that, but the index status does not update well, and it shows old information, I can fix it reindexing/clearing the index, or rebuilding track information, but I don't want to lose the indexed items.
Kevin avatar
in flag
What are you trying to do exactly? If you are updating config, usually you load it from its config factory by its ID.
rpayanm avatar
ru flag
@Kevin I updated the question.
Kevin avatar
in flag
I still don't understand what the point of this is. There are a variety of Drush commands for search API to index, clear, etc. I also don't see any explanation of why you are changing configuration programmatically or not using the config factory interface.
rpayanm avatar
ru flag
@KevinI I want to do it when some specific contents type are created.
leymannx avatar
ne flag
What's with https://drupal.stackexchange.com/q/309703/15055?
Score:1
gb flag

You can update the configuration of the search index with the following code

use Drupal\search_api\Entity\Index;

$index = Index::load('my_index');
$datasources = $index->getDatasources();
foreach ($datasources as $datasource_id => $datasource) {
  if ($datasource_id == 'entity:node') {
    $configuration = $datasource->getConfiguration();
    // This will add the 'page' bundle to the configuration.
    $configuration['bundles']['selected'][] = 'page';
    $datasources[$datasource_id]->setConfiguration($configuration);
  }
}
$index->save();

After saving the index, automatically a batch process will be called, if the changes are submitted in a form. Otherwise you manually need to add the new items to the index or reindex the whole index. For manually adding the new items, you can for example use the following code

$tracker = $index->getTrackerInstance();
$entity_type_manager = \Drupal::entityTypeManager();
$node_storage = $entity_type_manager->getStorage('node');
// Get the IDs of the new items.
$query = $node_storage->getQuery();
$query->condition('type', 'page');
$new_ids = $query->execute();
$entities = $node_storage->loadMultiple($new_ids);
$content_entity_tracking_manager = \Drupal::service('search_api.entity_datasource.tracking_manager');
foreach ($entities as $entity) {
  // Index the newly added item.
  $content_entity_tracking_manager->entityInsert($entity);
}

This may only works if you just have a few hundred new nodes, because you otherwise will get a timeout. Thats the reason, why the indexing happens in the batch process.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.