$npx -y skills add edutrul/drupal-ai --skill drupal-search-apiSearch API — index configuration, boost processors, field types, number field boosting, engagement metrics, and reindexing workflows.
| 1 | # Drupal Search API |
| 2 | |
| 3 | ## Index Configuration |
| 4 | |
| 5 | ### Field Type Requirements |
| 6 | |
| 7 | **Boolean Fields for Boosting** |
| 8 | - Boolean fields work best with custom boost processors |
| 9 | - Integer fields can cause issues with boolean-based boost logic |
| 10 | - Always configure boolean fields as `type: boolean` in index settings |
| 11 | |
| 12 | ```yaml |
| 13 | field_settings: |
| 14 | field_featured: |
| 15 | label: Featured |
| 16 | datasource_id: 'entity:node' |
| 17 | property_path: field_featured |
| 18 | type: boolean # NOT integer |
| 19 | boost: 8.0 |
| 20 | ``` |
| 21 | |
| 22 | **Configuration Command** |
| 23 | ```bash |
| 24 | ddev drush config:set search_api.index.{index_name} \ |
| 25 | field_settings.field_featured.type boolean |
| 26 | ``` |
| 27 | |
| 28 | ### Numeric Fields for Engagement Boosting |
| 29 | |
| 30 | **Flag Count Fields** |
| 31 | - Use `type: integer` for count fields |
| 32 | - Managed by `flag_search_api` module |
| 33 | - Automatically indexed and updated |
| 34 | |
| 35 | ```yaml |
| 36 | field_settings: |
| 37 | flag_bookmark_count: |
| 38 | label: 'Bookmark count' |
| 39 | property_path: flag_bookmark_count |
| 40 | type: integer |
| 41 | flag_favorite_count: |
| 42 | label: 'Favorite count' |
| 43 | property_path: flag_favorite_count |
| 44 | type: integer |
| 45 | ``` |
| 46 | |
| 47 | ## Boost Processors |
| 48 | |
| 49 | ### Custom Boolean Boost Processor |
| 50 | |
| 51 | **When to Use** |
| 52 | - Boolean field boosting (featured flags, promoted content) |
| 53 | - Needs 100% control over boost logic |
| 54 | - Complex conditional boosting |
| 55 | |
| 56 | **Pattern: FeaturedContentBoost.php** — extends `ProcessorPluginBase`, stage `preprocess_index` |
| 57 | |
| 58 | ```php |
| 59 | // Use #[SearchApiProcessor(...)] attribute (use Drupal\search_api\Attribute\SearchApiProcessor) — see README for full class |
| 60 | final class FeaturedContentBoost extends ProcessorPluginBase { |
| 61 | public function preprocessIndexItems(array $items) { |
| 62 | foreach ($items as $item) { |
| 63 | try { |
| 64 | $entity = $item->getOriginalObject()->getValue(); |
| 65 | if ($entity->hasField('field_featured') && |
| 66 | !$entity->get('field_featured')->isEmpty() && |
| 67 | $entity->get('field_featured')->value == 1) { |
| 68 | $item->setBoost($item->getBoost() * 2.0); |
| 69 | } |
| 70 | } |
| 71 | catch (\Exception $e) { |
| 72 | continue; |
| 73 | } |
| 74 | } |
| 75 | } |
| 76 | } |
| 77 | ``` |
| 78 | |
| 79 | **Key Points** |
| 80 | - Use multiplicative boost: `$item->setBoost($old_boost * boost_factor)` |
| 81 | - Pattern from `search_api_boolean_field_boost` module |
| 82 | - Boost at index time via `preprocess_index` stage |
| 83 | - Always get old boost first to preserve other boosts |
| 84 | |
| 85 | **Recommended Boost Factors** |
| 86 | - Featured content: `2.0x` (modest but effective) |
| 87 | - Featured content: `1.5x - 3.0x` |
| 88 | - Premium content: `1.5x - 2.0x` |
| 89 | |
| 90 | ### Number Field Boost Processor |
| 91 | |
| 92 | **When to Use** |
| 93 | - Engagement metrics (likes, bookmarks, views) |
| 94 | - Numeric quality scores |
| 95 | - Time-based decay factors |
| 96 | |
| 97 | **Configuration Pattern** |
| 98 | |
| 99 | ```yaml |
| 100 | processor_settings: |
| 101 | number_field_boost: |
| 102 | weights: |
| 103 | preprocess_index: 0 |
| 104 | boosts: |
| 105 | flag_bookmark_count: |
| 106 | boost_factor: 0.01 |
| 107 | aggregation: max |
| 108 | flag_favorite_count: |
| 109 | boost_factor: 0.1 |
| 110 | aggregation: max |
| 111 | ``` |
| 112 | |
| 113 | **How It Works** |
| 114 | - Adds to boost based on field value |
| 115 | - Formula: `boost += (field_value * boost_factor)` |
| 116 | - Example: 138 bookmarks x 0.01 = +1.38 boost |
| 117 | |
| 118 | **Configuration Commands** |
| 119 | ```bash |
| 120 | # Set bookmark count boost (0.01 per bookmark) |
| 121 | ddev drush config:set search_api.index.{index_name} \ |
| 122 | processor_settings.number_field_boost.boosts.flag_bookmark_count.boost_factor 0.01 |
| 123 | |
| 124 | # Set favorite count boost (0.1 per favorite) |
| 125 | ddev drush config:set search_api.index.{index_name} \ |
| 126 | processor_settings.number_field_boost.boosts.flag_favorite_count.boost_factor 0.1 |
| 127 | ``` |
| 128 | |
| 129 | **Recommended Boost Factors** |
| 130 | - Bookmark count: `0.01 - 0.05` (for counts in 10-1000 range) |
| 131 | - Favorite count: `0.1 - 0.5` (for counts in 1-50 range) |
| 132 | - View count: `0.001 - 0.01` (for counts in 100-10000 range) |
| 133 | |
| 134 | ### Processor Conflicts |
| 135 | |
| 136 | **Problem: Multiple Processors on Same Field** |
| 137 | |
| 138 | If multiple processors target the same field, they can conflict: |
| 139 | - One overrides the other |
| 140 | - Boosts don't combine as expected |
| 141 | - Unpredictable results |
| 142 | |
| 143 | **Solution: Remove Conflicting Configuration** |
| 144 | |
| 145 | ```bash |
| 146 | # Remove field from number_field_boost if using custom processor |
| 147 | ddev drush config:set search_api.index.{index_name} \ |
| 148 | processor_settings.number_field_boost.boosts.field_featured null |
| 149 | ``` |
| 150 | |
| 151 | **Best Practice** |
| 152 | - Use custom processor for boolean/complex logic |
| 153 | - Use number_field_boost for simple numeric boosts |
| 154 | - Don't configure same field in multiple processors |
| 155 | |
| 156 | ## Configuration Management |
| 157 | |
| 158 | ### Direct Config Updates with PHP |
| 159 | |
| 160 | When `drush config:set` fails or produces unexpected results (e.g., side effects on unrelated config), use PHP to directly update active configuration: |
| 161 | |
| 162 | ```bash |
| 163 | ddev drush php:eval " |
| 164 | \$config = \Drupal::configFactory()->getEditable('search_api.index.{index_name}'); |
| 165 | |
| 166 | // Set field type |
| 167 | \$config->set('field_settings.field_featured.type', 'boolean'); |
| 168 | |
| 169 | // Remove from number_field_boost |
| 170 | \$boosts = \$config->get('processor_settings.number_field_boost.boosts'); |
| 171 | unset(\$boosts['field_featured']); |
| 172 | \$c |