If a processor is added to an index via hook_default_search_api_index_alter(), for example:

function hook_default_search_api_index_alter(&$data) {
  if (isset($data['database_node_index'])) {
    $data['database_node_index']->options['processors']['my_custom_processor'] = array(
      'status' => 0,
      'weight' => 15,
      'settings' => array(
        'fields' => array(
          'title' => TRUE,
          'body:summary' => TRUE,
        ),
      ),
    );
  }
}

The 'weight' given won't actually affect the order that the processors are run.

So, if, for example, there was already a processor exported on the index that had a 'weight' of 20, we'd want our 'my_custom_processor' to run before it, but it'd actually be run after, because search_api is using array order (and this item was altered in later) rather than the 'weight'.

However, if you edit the index, go to the 'Filter' tab, and save the form without any changes, then the processors will be saved in the correct order by 'weight'. So, 'weight' is respected on the form (and affects the order the processors are saved on the array), but it doesn't have an affect on the order of processors when the index is loaded.

I think this is bug! I'll post a patch to fix it in a moment.

Comments

dsnopek created an issue. See original summary.

dsnopek’s picture

Status: Active » Needs review
StatusFileSize
new476 bytes

Here's a patch that fixes this in my testing!

drunken monkey’s picture

StatusFileSize
new2.36 KB

Thanks for reporting this issue! However, this is an edge case, and I’m not sure how to treat it.
First off, this isn’t really a bug, at least not completely, as the behavior is expected. Instead of sorting the processors every time we get them, we just sort them once before saving an index – which saves time, of course. For that, we have the following code in search_api_admin_index_workflow_submit():

// Save the already sorted arrays to avoid having to sort them at each use.
uasort($index->options['data_alter_callbacks'], 'search_api_admin_element_compare');
uasort($index->options['processors'], 'search_api_admin_element_compare');

So, this is completely on purpose. However, it of course suffers the same problem a lot of older Drupal code has: Completely relying on changes happening solely via the UI, having data validation/sanitization code only in the form functions, not built into the underlying entity CRUD operations.

Maybe just moving the code to a better suited location (SearchApiIndex::save()) would already resolve your problem? (Or might need hook_search_api_index_presave() instead, as that’s more reliable.)
I’m not 100% sure which of those places, if any, would be triggered by a default index. But would be great if you could try it out and provide feedback!
Thanks again, in any case!

drunken monkey’s picture

Component: General code » Framework
benstallings’s picture

Status: Needs review » Closed (outdated)

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.