mcpField
D
drupal-search-api

drupal-search-api

github.com/grasmash開発82230 回インストール4 週間前に更新
リポジトリ

drupal-search-api について

Drupal Search API を設定する開発者向けのパターンガイドです。インデックスのフィールド、ブーストプロセッサー、設定管理を扱い、ブール値や数値によるブースト、再インデックス、結果検証を説明します。

主な機能

  1. 01ブール値・数値フィールドの設定
  2. 02カスタムブーストプロセッサーの作成
  3. 03コンテンツと反応指標のブースト併用
  4. 04Search API 設定の管理と検証
  5. 05検索インデックスの消去と再構築
  6. 06検索結果と順位のテスト

活用シーン

  1. 01注目コンテンツの検索順位を上げる
  2. 02ブックマーク数や閲覧数で順位を調整する
  3. 03プロセッサーの競合やブースト不作動を調べる
  4. 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 による設定更新後:

  1. 変更を確認します:ddev drush config:get search_api.index.{index_name} field_settings.field_featured
  2. そのオブジェクトだけをエクスポートします:ddev drush config:get search_api.index.{index_name} --format=yaml > config/default/search_api.index.{index_name}.yml(一括の config:export では無関係な差分も取り込まれます。drupal-config-mgmt スキルを参照してください)
  3. エクスポートされた変更を確認します:git diff config/default/
  4. 意図しない変更(例: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}

防止策:

  1. ローカル開発用に search_api.server.{server_name}.yml を変更しないでください
  2. サーバー設定を変更せず、DDEV に組み込まれた Solr サービスを使用してください
  3. サーバー設定の変更が必要な場合は、環境固有の設定に設定スプリットを使用してください
  4. コミット前に必ず 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 ステージで適用します
  • トラフィックの多い検索でよりスケールします
  • 再インデックスが必要でも許容できます
ブーストの積み重ね

ブーストの組み合わせ方

  1. 基本関連性スコア(Solr から取得)
  2. 注目コンテンツのブースト:score x 2.0
  3. ブックマーク数のブースト:score + (bookmarks x 0.01)
  4. お気に入り数のブースト: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

よくある問題

問題:ブーストが適用されない

症状

  • 結果が期待どおりの順位にならない
  • 再インデックス後も変化がない

確認項目

  1. インデックス設定でプロセッサが有効になっている
  2. フィールドタイプが正しい(boolean/integer)
  3. 全件の再インデックスが完了している
  4. 競合するプロセッサがない
  5. 設定変更後にキャッシュがクリアされている

デバッグコマンド

# 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. 控えめなブースト(1.5x または 0.01)から始めます
  2. 既知のクエリでテストします
  3. 効果が見えるまで少しずつ上げます
  4. 最適なレベルまで下げます

モジュールの依存関係

必須モジュール
  • search_api - Search API のコアモジュール
  • search_api_solr - Solr バックエンド(Solr を使用する場合)
オプションのモジュール
  • flag_search_api - フラグ数(ブックマーク、お気に入り)のインデックス作成
  • search_api_boolean_field_boost - ブーストパターンの参考

参考資料

Search API プロセッサーの開発
ブースト戦略
Flag Search API

コメント