drupal-search-api について
Drupal Search API を設定する開発者向けのパターンガイドです。インデックスのフィールド、ブーストプロセッサー、設定管理を扱い、ブール値や数値によるブースト、再インデックス、結果検証を説明します。
主な機能
- 01ブール値・数値フィールドの設定
- 02カスタムブーストプロセッサーの作成
- 03コンテンツと反応指標のブースト併用
- 04Search API 設定の管理と検証
- 05検索インデックスの消去と再構築
- 06検索結果と順位のテスト
活用シーン
- 01注目コンテンツの検索順位を上げる
- 02ブックマーク数や閲覧数で順位を調整する
- 03プロセッサーの競合やブースト不作動を調べる
- 04設定変更後に再インデックスして検証する
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ grasmash/ drupal-claude-skills --skill drupal-search-apiインストール後、Claude Code で/drupal-search-apiを入力して読み込まれたか確認します。
詳細
Drupal Search API のパターン
このスキルでは、Drupal サイト向けの Search API の設定パターン、ブースト戦略、カスタムプロセッサの開発について説明します。
インデックスの設定
フィールドタイプの要件
ブースト用のブール型フィールド
- ブール型フィールドはカスタムブーストプロセッサとの相性が最適です
- 整数型フィールドは、ブール値に基づくブーストロジックで問題を引き起こすことがあります
- インデックス設定では、必ずブール型フィールドを
type: booleanとして設定してください
field_settings:
field_featured:
label: Featured
datasource_id: 'entity:node'
property_path: field_featured
type: boolean # NOT integer
boost: 8.0
設定コマンド
ddev drush config:set search_api.index.{index_name} \
field_settings.field_featured.type boolean
エンゲージメントブースト用の数値フィールド
フラグ数フィールド
- 件数フィールドには
type: integerを使用します flag_search_apiモジュールによって管理されます- 自動的にインデックス化および更新されます
field_settings:
flag_bookmark_count:
label: 'Bookmark count'
property_path: flag_bookmark_count
type: integer
flag_favorite_count:
label: 'Favorite count'
property_path: flag_favorite_count
type: integer
ブーストプロセッサ
カスタムブール型ブーストプロセッサ
使用する場面
- ブール型フィールドのブースト(注目フラグ、プロモーション対象コンテンツ)
- ブーストロジックを完全に制御する必要がある場合
- 複雑な条件付きブースト
パターン:FeaturedContentBoost.php
<?php
namespace Drupal\custom_search\Plugin\search_api\processor;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\Processor\ProcessorPluginBase;
/**
* @SearchApiProcessor(
* id = "featured_content_boost",
* label = @Translation("Featured content boost"),
* description = @Translation("Adds a boost to indexed items marked as featured."),
* stages = {
* "preprocess_index" = 0,
* },
* locked = false,
* hidden = false,
* )
*/
class FeaturedContentBoost extends ProcessorPluginBase {
/**
* {@inheritdoc}
*/
public function preprocessIndexItems(array $items) {
/** @var \Drupal\search_api\Item\ItemInterface $item */
foreach ($items as $item) {
try {
$entity = $item->getOriginalObject()->getValue();
// Check if entity has featured field and it's set to TRUE.
if ($entity->hasField('field_featured') &&
!$entity->get('field_featured')->isEmpty() &&
$entity->get('field_featured')->value == 1) {
$old_boost = $item->getBoost();
// Apply 2x boost to featured content.
$item->setBoost($old_boost * 2.0);
}
}
catch (\Exception $e) {
// Skip items that can't be loaded.
continue;
}
}
}
}
重要なポイント
- 乗算ブーストを使用します:
$item->setBoost($old_boost * boost_factor) search_api_boolean_field_boostモジュールのパターンですpreprocess_indexステージでインデックス作成時にブーストします- 他のブーストを維持するため、必ず最初に既存のブースト値を取得してください
推奨ブースト係数
- 注目コンテンツ:
2.0x(控えめながら効果的) - 注目コンテンツ:
1.5x - 3.0x - プレミアムコンテンツ:
1.5x - 2.0x
数値フィールドブーストプロセッサ
使用する場面
- エンゲージメント指標(いいね、ブックマーク、閲覧数)
- 数値による品質スコア
- 時間に基づく減衰係数
設定パターン
processor_settings:
number_field_boost:
weights:
preprocess_index: 0
boosts:
flag_bookmark_count:
boost_factor: 0.01
aggregation: max
flag_favorite_count:
boost_factor: 0.1
aggregation: max
仕組み
- フィールド値に基づいてブースト値を加算します
- 計算式:
boost += (field_value * boost_factor) - 例:ブックマーク数 138 x 0.01 = ブースト値 +1.38
設定コマンド
# Set bookmark count boost (0.01 per bookmark)
ddev drush config:set search_api.index.{index_name} \
processor_settings.number_field_boost.boosts.flag_bookmark_count.boost_factor 0.01
# Set favorite count boost (0.1 per favorite)
ddev drush config:set search_api.index.{index_name} \
processor_settings.number_field_boost.boosts.flag_favorite_count.boost_factor 0.1
推奨ブースト係数
- ブックマーク数:
0.01 - 0.05(件数が 10-1000 の場合) - お気に入り数:
0.1 - 0.5(件数が 1-50 の場合) - 閲覧数:
0.001 - 0.01(件数が 100-10000 の場合)
プロセッサの競合
問題:同じフィールドに対する複数のプロセッサ
複数のプロセッサが同じフィールドを対象にすると、競合することがあります:
- 一方がもう一方を上書きします
- ブーストが想定どおりに組み合わされません
- 結果が予測できなくなります
解決策:競合する設定を削除する
# Remove field from number_field_boost if using custom processor
ddev drush config:set search_api.index.{index_name} \
processor_settings.number_field_boost.boosts.field_featured null
ベストプラクティス
- ブール値や複雑なロジックにはカスタムプロセッサを使用します
- 単純な数値ブーストには number_field_boost を使用します
- 同じフィールドを複数のプロセッサで設定しないでください
設定管理
PHP による設定の直接更新
drush config:set が失敗する場合や、予期しない結果(例:無関係な設定への副作用)が発生する場合は、PHP を使ってアクティブな設定を直接更新します:
ddev drush php:eval "
\$config = \Drupal::configFactory()->getEditable('search_api.index.{index_name}');
// Set field type
\$config->set('field_settings.field_featured.type', 'boolean');
// Remove from number_field_boost
\$boosts = \$config->get('processor_settings.number_field_boost.boosts');
unset(\$boosts['field_featured']);
\$config->set('processor_settings.number_field_boost.boosts', \$boosts);
// Set boost factors
\$config->set('processor_settings.number_field_boost.boosts.flag_bookmark_count.boost_factor', 0.01);
\$config->set('processor_settings.number_field_boost.boosts.flag_favorite_count.boost_factor', 0.1);
\$config->save();
echo \"Configuration updated\n\";
"
drush config:set の代わりに PHP を使用する場面:
- config:set によって望ましくない副作用が発生する場合(例:
server: {server_name}がserver: nullに変更される) - 配列キーを削除する場合(
nullよりも unset パターンが適しています) - 関連する複数の変更をまとめて適用する場合
- フィールドタイプの変更によって Drupal が汎用タイプにフォールバックする場合
PHP による設定更新後:
- 変更を確認します:
ddev drush config:get search_api.index.{index_name} field_settings.field_featured - そのオブジェクトだけをエクスポートします:
ddev drush config:get search_api.index.{index_name} --format=yaml > config/default/search_api.index.{index_name}.yml(一括のconfig:exportでは無関係な差分も取り込まれます。drupal-config-mgmtスキルを参照してください) - エクスポートされた変更を確認します:
git diff config/default/ - 意図しない変更(例:ngram フィールドがプレーンテキストに変更されている場合)を元に戻します
フィールドタイプの保持
問題: Solr サーバー設定を変更すると(たとえば、別のバックエンドを指定する場合)、設定のエクスポートによってカスタムフィールドタイプが汎用タイプに格下げされることがあります。
# BEFORE (correct)
field_display_name:
type: 'solr_text_custom:ngramstring'
# AFTER export (incorrect)
field_display_name:
type: text
解決策: エクスポート後、PHP を使用してカスタムフィールドタイプを復元します。
ddev drush php:eval "
\$config = \Drupal::configFactory()->getEditable('search_api.index.{index_name}');
\$config->set('field_settings.field_display_name.type', 'solr_text_custom:ngramstring');
\$config->set('field_settings.label.type', 'solr_text_custom:ngramstring');
\$config->set('field_settings.name.type', 'solr_text_custom:ngramstring');
\$config->set('field_settings.title.type', 'solr_text_custom:ngramstring');
\$config->save();
"
ddev drush config:get search_api.index.{index_name} --format=yaml > config/default/search_api.index.{index_name}.yml
ngram トークナイズを使用するフィールド:
field_display_name- 表示名(オートコンプリートの部分一致)label- エンティティのラベル/タイトルname- ユーザーアカウント名title- ノードのタイトル
これらを type: text に変更しないでください。 部分的な名前検索が機能しなくなります(例:「mich」で「Michael」が見つからなくなります)。
設定エクスポートの副作用
Search API サーバー設定を変更すると(たとえば、ローカル開発用に変更する場合)、Drupal がサーバー依存関係を削除するようにインデックス設定を更新することがあります。
# Unintended change in search_api.index.{index_name}.yml
dependencies:
config:
- - search_api.server.{server_name} # Removed
server: null # Changed from {server_name}
防止策:
- ローカル開発用に
search_api.server.{server_name}.ymlを変更しないでください - サーバー設定を変更せず、DDEV に組み込まれた Solr サービスを使用してください
- サーバー設定の変更が必要な場合は、環境固有の設定に設定スプリットを使用してください
- コミット前に必ず
git diff config/default/を確認してください
復旧:
# Revert index files if server was set to null
git checkout HEAD -- config/default/search_api.index.*.yml
変更後の再インデックス
再インデックスが必要な場合
次の場合は必ず再インデックスしてください:
- フィールドタイプの変更(integer -> boolean)
- ブースト係数の変更
- プロセッサの追加/削除
- プロセッサ設定の変更
再インデックスコマンド
# Full reindex workflow
ddev drush cr
ddev drush search-api:clear {index_name}
ddev drush search-api:index {index_name}
# Check index status
ddev drush search-api:status {index_name}
部分的な再インデックス
# Index only remaining items (incremental)
ddev drush search-api:index {index_name}
# Clear and reindex specific items (not available in core)
# Use full reindex instead
ブーストのテスト
Search API の Drush コマンド
# Test search via drush
ddev drush search-api:search {index_name} "search query"
# Check indexed values
ddev drush search-api:status {index_name}
Web エンドポイントのテスト
# Test via web search endpoint
curl -H "Accept: application/vnd.api+json" \
"https://example.com/search-api/web-search?query=test"
# Parse results with Python
curl -s "https://example.com/search-api/web-search?query=test" | \
python3 -c "import sys, json; data = json.load(sys.stdin); \
[print(f'{i+1}. {item[\"attributes\"][\"title\"]}') \
for i, item in enumerate(data['data'][:10])]"
検証クエリ
ブックマーク数の確認
SELECT u.uid, u.name, fcf.count AS bookmark_count
FROM users_field_data u
LEFT JOIN flag_counts fcf ON fcf.entity_type = 'user'
AND fcf.entity_id = u.uid
AND fcf.flag_id = 'bookmark'
ORDER BY fcf.count DESC
LIMIT 10;
お気に入り数の確認
SELECT n.nid, n.title, fcl.count AS favorite_count
FROM node_field_data n
INNER JOIN flag_counts fcl ON fcl.entity_type = 'node'
AND fcl.entity_id = n.nid
AND fcl.flag_id = 'favorite'
WHERE n.type = 'article'
ORDER BY fcl.count DESC
LIMIT 10;
パフォーマンスに関する考慮事項
インデックス時とクエリ時のブースト
インデックス時のブースト(推奨)
- パフォーマンスが向上します(インデックス作成時に一度だけ計算されます)
- クエリ数が多い場合にもスケールします
- ブーストロジックを変更した場合は再インデックスが必要です
- ブーストは静的です(クエリごとに調整できません)
クエリ時のブースト
- 動的です(クエリごとに調整できます)
- 変更時に再インデックスは不要です
- すべてのクエリでパフォーマンスに影響します
- Search API での実装が複雑です
推奨パターン:インデックス時のブースト
- すべてのブーストを
preprocess_indexステージで適用します - トラフィックの多い検索でよりスケールします
- 再インデックスが必要でも許容できます
ブーストの積み重ね
ブーストの組み合わせ方
- 基本関連性スコア(Solr から取得)
- 注目コンテンツのブースト:
score x 2.0 - ブックマーク数のブースト:
score + (bookmarks x 0.01) - お気に入り数のブースト:
score + (favorites x 0.1)
計算例
Node: "Getting Started with Drupal" (featured, 138 bookmarks)
- Base score: 1.0
- Featured: 1.0 x 2.0 = 2.0
- 138 bookmarks: 2.0 + (138 x 0.01) = 3.38
- Final boost: 3.38
Node: "Advanced Drupal Techniques"
- Base score: 1.0
- 12 favorites: 1.0 + (12 x 0.1) = 2.2
- Final boost: 2.2
よくある問題
問題:ブーストが適用されない
症状
- 結果が期待どおりの順位にならない
- 再インデックス後も変化がない
確認項目
- インデックス設定でプロセッサが有効になっている
- フィールドタイプが正しい(boolean/integer)
- 全件の再インデックスが完了している
- 競合するプロセッサがない
- 設定変更後にキャッシュがクリアされている
デバッグコマンド
# Check processor configuration
ddev drush config:get search_api.index.{index_name} processor_settings
# Check field configuration
ddev drush config:get search_api.index.{index_name} field_settings
# Verify index status
ddev drush search-api:status {index_name}
問題:ブーストが強すぎる/弱すぎる
症状
- 関連性の低い結果が上位に表示される
- 重要な結果が十分に上位に表示されない
解決策:ブースト係数を調整する
強すぎる場合(関連性を圧倒する場合):
- 乗算ブーストを下げます(2.0 -> 1.5)
- 加算ブースト係数を下げます(0.1 -> 0.05)
弱すぎる場合(目に見える効果がない場合):
- ブースト係数を少しずつ上げます
- 極端な値で動作を確認してから、適切な値まで下げます
テストパターン
- 控えめなブースト(1.5x または 0.01)から始めます
- 既知のクエリでテストします
- 効果が見えるまで少しずつ上げます
- 最適なレベルまで下げます
モジュールの依存関係
必須モジュール
search_api- Search API のコアモジュールsearch_api_solr- Solr バックエンド(Solr を使用する場合)
オプションのモジュール
flag_search_api- フラグ数(ブックマーク、お気に入り)のインデックス作成search_api_boolean_field_boost- ブーストパターンの参考
参考資料
Search API プロセッサーの開発
ブースト戦略
Flag Search API
- Flag Search API モジュール
- エンゲージメント指標用のフラグ数のインデックス作成を提供します