Add 2 hooks:

  • hook_search_api_solr_index_field() - in SearchApiSolrService::indexItems() method - to provide an option to change both solr property which the value obtained from Search API is being stored in as well as the value itself (for example to store multilingual values in language-based dynamic fields),
  • hook_search_api_solr_extract_field() - in SearchApiSolrService::extractResults() method - to provide an option to change both Search API property which the value obtained from solr will be assigned to as well as the value itself.

The Search API Entity Translation Solr search module should be the best explanation of the reasoning behind this request.

Patch to follow.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

maciej.zgadzaj’s picture

Status: Active » Needs review
FileSize
5.78 KB

Patch attached.

drunken monkey’s picture

Wouldn't hook_search_api_solr_query_alter(), hook_search_api_solr_search_results_alter() and hook_search_api_solr_field_mapping_alter() suffice for that?

maciej.zgadzaj’s picture

I don't think that the existing hooks suffice, but perhaps I've missed something here, so I'll try to explain my logic behind those new hooks:

First, hook_search_api_solr_query_alter() is already being used, to make sure that all language-specific solr fields are being searched through for each of Drupal's multilingual fields. Because of this, this query alter hook implementation needs to be run as the very last of all other implementations, as other modules might add extra fields to search query, and for each of those potentially added fields we would need to add all relevant language-specific fields. Hence the module weight is being set to such high value in the .install file.

Now, regarding indexing process - it's true that existing hook_search_api_solr_field_mapping_alter() does something similar to the new hook_search_api_solr_index_field(), but it's not enough. The problem is that the mapping might (and will) be different for each item, so we need to be able to change it dynamically during indexing, which the original hook is not able to do. For example, the same Drupal/Search API field (say, body) will be mapped to en_body for items in English, de_body for items in German etc. So hook_search_api_solr_index_field() seems to be needed.

Re searching and hook_search_api_solr_extract_field() - existing hook_search_api_solr_search_results_alter() might work here, the problem though is that, combined with high module weight, and thus this module's hook implementation running at the very end, other modules implementing this hook will get unprocessed result data, still in language-specific fields (not the expected standard ones), which I believe is not a very good idea, as all that language-field-shifting-voodoo should be as invisible as possible, and any hook_search_api_solr_search_results_alter() implementation should always get data in expected standard fields.

maciej.zgadzaj’s picture

Btw, if you'd like to discuss this further in a more interactive way I'm on IRC as mzgadzaj

drunken monkey’s picture

First, hook_search_api_solr_query_alter() is already being used, to make sure that all language-specific solr fields are being searched through for each of Drupal's multilingual fields. Because of this, this query alter hook implementation needs to be run as the very last of all other implementations, as other modules might add extra fields to search query, and for each of those potentially added fields we would need to add all relevant language-specific fields. Hence the module weight is being set to such high value in the .install file.

You should use hook_module_implements_alter() instead of changing the module weight, if only a single hook is the reason. That would also eliminate the problem with hook_search_api_solr_search_results_alter(), which you describe in the last paragraph.

Now, regarding indexing process - it's true that existing hook_search_api_solr_field_mapping_alter() does something similar to the new hook_search_api_solr_index_field(), but it's not enough. The problem is that the mapping might (and will) be different for each item, so we need to be able to change it dynamically during indexing, which the original hook is not able to do. For example, the same Drupal/Search API field (say, body) will be mapped to en_body for items in English, de_body for items in German etc. So hook_search_api_solr_index_field() seems to be needed.

OK, that makes sense. However, calling a hook for every single field of every document seems to me to still be an unjustified performance drag for everyone not using this, and possible even for those that do.
How about adding a hook_search_api_solr_document_alter() (there's already an almost-RTBC patch at #1246730: Proper way to alter the Solr Document) to enable altering each document before it is sent?
Maybe letting it receive all documents of a batch at once would be even better, both performance- and feature-wise.

Btw, if you'd like to discuss this further in a more interactive way I'm on IRC as mzgadzaj

OK, thanks. I'm rather busy at the moment (or, rather, the whole time) but maybe I'll go online and look for you in the next days.

maciej.zgadzaj’s picture

#1246730: Proper way to alter the Solr Document looks good, and it should be ok for my purposes. If that gets merged, I'm perfectly fine with won't fixing this issue.

drunken monkey’s picture

Status: Needs review » Closed (won't fix)

OK, then let's work on that issue.