Problem/Motivation

I'm using Acquia Connector 1.19.0 which requires Search API ^1.8. I'm on Search API 1.15.0, Search API SOLR 1.4.0, Drupal Core 8.8.6. (It's possible this ticket belongs on one of those other modules.)

I want to add a computed value to a SOLR document. That is, I want to add a field to my search index, but I do not want that field to be added via the Drupal admin index field settings because the field is dynamically generated.

I assume https://www.drupal.org/docs/8/modules/search-api/developer-documentation... is the documentation to achieve that.

After following the documentation, I found I could not achieve this feature. I also tried following https://drupal.stackexchange.com/a/218130 which suggests following the AddURL processor.

Here is the basics of the solution I used, I have not tested this exact code!

Part 1: The processor

namespace Drupal\mymodule\Plugin\search_api\processor;

use Drupal\search_api\Item\Field;
use Drupal\search_api\Processor\FieldsProcessorPluginBase;

/**
 * Populates a computed field.
 *
 * @SearchApiProcessor(
 *   id = "add_computed_field",
 *   label = @Translation("Add a Computed Field"),
 *   description = @Translation("Add a computed field that only exists in the SOLR documents."),
 *   stages = {
 *     "pre_index_save" = 0,
 *     "preprocess_index" = 0,
 *     "preprocess_query" = 0,
 *   }
 * )
 */
class PopulateComputedField extends FieldsProcessorPluginBase {

  /**
   * {@inheritdoc}
   */
  public function preprocessIndexItems(array $items) {
    /** @var \Drupal\search_api\Item\Item $item */
    foreach ($items as $item) {
      $computed_fields = [];
      $computed_fields['fts_computed_field_1'] = new Field($item->getIndex(), 'fts_computed_field_1');
      $computed_fields['fts_computed_field_1']->setValues(['10.00'])->setType('decimal');
      $computed_fields['fts_computed_field_2'] = new Field($item->getIndex(), 'fts_computed_field_1');
      $computed_fields['fts_computed_field_2']->setValues(['20.00'])->setType('decimal');

      $fields = $item->getFields();
      $fields += $computed_fields;
      $item->setFields($fields);
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function testType($type) {
    return 'decimal' == $type;
  }

}

Part 2: Allow those fields to be added

The above processor will throw an exception because those computed names don't exist on the index. Therefore, you must do the following to tell Search API its OK to add those fields:

use Drupal\search_api\IndexInterface;

function mymodule_search_api_solr_field_mapping_alter(IndexInterface $index, array &$fields) {
  $fields['fts_computed_field_1'] = 'fts_computed_field_1';
  $fields['fts_computed_field_2'] = 'fts_computed_field_2';
}

Proposed resolution

The purpose of this ticket is to help understand why that documentation did not work, ideally to help others (and my future self) know how to accomplish this goal.

Perhaps an output of this ticket is a new documented recipe? Perhaps the answer is simply Acquia Connector needs to support a newer version of Search API + SOLR and then the already written documentation will work?

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Comments

josephdpurcell created an issue. See original summary.

josephdpurcell’s picture

Issue summary: View changes
mkalkbrenner’s picture

The field type mapping is wrong. You need to map from the Search API field name to the Solr internal field name. The Solr field name has a type based prefix.

In 4.x there're more ways to do customize fields.

mkalkbrenner’s picture

Status: Active » Fixed

no further feedback

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.