web-dev-qa-db-ja.com

特定のコンテンツタイプをインデックスに登録しない

デフォルトのDrupal 7検索のために、特定のコンテンツタイプにインデックスを付けたいだけです。他のモジュールをインストールせずにこれを実行したいと思います。

これを行うには、search_datasetからすべてのノードを取得するクエリ(hook_query_alterを使用)にフックします。このクエリは、node_update_index関数(node.module)にあります。

$result = db_query_range("SELECT n.nid FROM {node} n LEFT JOIN {search_dataset} d ON d.type = 'node' AND d.sid = n.nid WHERE d.sid IS NULL OR d.reindex <> 0 ORDER BY d.reindex ASC, n.nid ASC", 0, $limit, array(), array('target' => 'slave'));

問題は、フックでこのクエリを変更する機能を取得できないことです。私のコードは次のとおりです。

function mymodule_query_alter(&$query) {
  var_dump((string)$query);
}

ある時点で、db_query_rangeクエリが出力されます。また、デバッグをファイルに出力して、ajax時間で実行されているクエリをキャッチできるようにしました。

私が間違っているかもしれないことについてのアイデアはありますか?

4
Birk

タグ付けされているSQLクエリのみ変更できますが、これはタグ付けされていません。したがって、HOOK_query_alter()を使用して、達成しようとしていることを行うことはできません。

これはハッキーですが、これを行う最も簡単な方法は hook_module_implements_alter() を実装し、Nodeモジュールのhook_update_index()実装が起動しないようにすることです。その後、コピーできます node_update_index() 関数をカスタムモジュールに追加し、関数名の「node」をカスタムモジュールの名前に置き換え、クエリのみを変更して、必要なノードタイプを除外します。

/**
 * Implements hook_module_implements_alter().
 */
function mymodule_module_implements_alter(&$implementations, $hook) {
  if ('update_index' == $hook) {
    unset($implementations['node']);
  }
}

/**
 * Implements hook_update_index().
 * 
 * @see node_update_index().
 */
function mymodule_update_index() {
  $limit = (int)variable_get('search_cron_limit', 100);

  $result = db_query_range( /* Your custom query here */ );

  foreach ($result as $node) {
    _node_index_node($node);
  }
}
6
Chris Pliakas

まあ、あなたは Custom Search がすることを借りることができます:

function custom_search_query_alter(QueryAlterableInterface $query) {
  if ($query->hasTag('node_access') && $query->hasTag('pager')) {
    $excluded_types = array_filter(variable_get('custom_search_' . variable_get('custom_search_delta', '') . 'node_types_excluded', array()));
    if (!empty($excluded_types)) {
      $tables = $query->getTables();
      foreach ($tables as $table) {
        if ($table['table'] == 'search_index') {
          $query->condition('n.type', $excluded_types, 'NOT IN');
        }
      }
    }
  }
}

コンテンツタイプの$excluded_types = ...行を編集するだけで済みます。

2
mpdonadio

Chris Pliakasの answer は、おそらくコアの変更が原因で機能しなくなりました。 Drupal 7.22:

_
/**
 * Implements hook_module_implements_alter().
 */
function my_module_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'cron') {
    unset($implementations['search']);
  }
}

/**
 * Implements hook_cron().
 *
 * @see search_cron()
 */
function my_module_cron() {
  // We register a shutdown function to ensure that search_total is always up
  // to date.
  drupal_register_shutdown_function('search_update_totals');

  foreach (variable_get('search_active_modules', array('node', 'user')) as $module) {
    // Update Word index
    $module == 'node' ? module_invoke('my_module', 'update_index') : module_invoke($module, 'update_index');
  }
}

/**
 * Implements hook_update_index().
 * 
 * @see node_update_index()
 */
function my_module_update_index() {
  $limit = (int)variable_get('search_cron_limit', 100);

  // Only index the artist and label content types.
  $result = db_query_range("SELECT n.nid FROM {node} n LEFT JOIN {search_dataset} d ON d.type = 'node' AND d.sid = n.nid WHERE (d.sid IS NULL OR d.reindex  0) AND n.type IN (:types) ORDER BY d.reindex ASC, n.nid ASC", 0, $limit, array(':types' => array('artist', 'label')), array('target' => 'slave'));

  foreach ($result as $node) {
    _node_index_node($node);
  }
}
_

基本的に、my_module_cron()の代わりに、独自のsearch_cron()実装をプラグインします。ここで、node_update_index()呼び出しをmy_module_update_index()に置き換えます。 my_module_update_index()には、インデックス付けのために特定のタイプのノードのみを選択する変更されたクエリがあります。

0
jamix