Я очень новичок в Drupal и пытаюсь создать модуль, который позволит администраторам отмечать узлы ключевыми словами, чтобы повысить количество узлов в верхней части результатов поиска.Изменение условия поиска для набора данных в Drupal 7
У меня есть отдельная таблица БД для ключевых слов и соответствующих идентификаторов узлов. Эта таблица UNIONed с таблицей search_index через hook_query_alter ...
function mos_search_result_forcer_query_alter(QueryAlterableInterface &$query) {
if (get_class($query) !== 'PagerDefault') { //<< check this because this function will mod all queries elsewise
return;
}
// create unioned search index result set...
$index = db_select('search_index', 's');
$index->addField('s', 'sid');
$index->addField('s', 'word');
$index->addField('s', 'score');
$index->addField('s', 'type');
$msrfi = db_select('mos_search_result_forcer', 'm');
$msrfi->addField('m', 'nid', 'sid');
$msrfi->addField('m', 'keyword', 'word');
$msrfi->addExpression('(SELECT MAX(score) + m.id/(SELECT MAX(id) FROM {mos_search_result_forcer}) FROM {search_index})', 'score');
$msrfi->addExpression(':type', 'type', array(':type' => 'node'));
$index->union($msrfi);
$tables =& $query->getTables();
$tables['i']['table'] = $index;
return $query;
}
Drupal затем генерирует почти правильный запрос ...
SELECT
i.type AS type, i.sid AS sid, SUM(CAST('10' AS DECIMAL) * COALESCE(((12.048628015788 * i.score * t.count)), 0)/CAST('10' AS DECIMAL)) AS calculated_score
FROM (
SELECT
s.sid AS sid, s.word AS word, s.score AS score, s.type AS type
FROM
search_index s
UNION SELECT
m.nid AS sid, m.keyword AS word, (
SELECT
MAX(score) + m.id/(SELECT MAX(id) FROM mos_search_result_forcer)
FROM
search_index
) AS score, 'node' AS type
FROM
mos_search_result_forcer m
) i
INNER JOIN node n ON n.nid = i.sid
INNER JOIN search_total t ON i.word = t.word
INNER JOIN search_dataset d ON i.sid = d.sid AND i.type = d.type
WHERE (n.status = '1')
AND((i.word = 'turtles'))
AND (i.type = 'node')
/* this is the problem line... */
AND((d.data LIKE '% turtles %' ESCAPE '\\'))
/* ...end problem line */
GROUP BY i.type, i.sid
HAVING (COUNT(*) >= '1')
ORDER BY calculated_score DESC
LIMIT 10 OFFSET 0
... Мне нужно, что "проблема линия" в читать ...
AND((d.data LIKE '% turtles %' ESCAPE '\\') OR (d.sid IN (SELECT nid FROM mos_search_result_forcer)))
... какой крюк я могу использовать, чтобы добавить это условие ИЛИ?
- Я не хочу взламывать ядро Drupal.
- Я не хочу менять союз/подзапросы (не мое решение).
- Я буду оптимизировать запросы позже - функциональность важнее.
Спасибо, умные люди!
спасибо! Этот код на самом деле очень похож на код, который я экспериментировал; однако проблема заключается в том, что условие, которое мне нужно изменить, добавляется в объект запроса * после вызова hook_query_alter. Я надеялся, что может быть еще один крючок, который вызывается непосредственно перед вызовом метода запроса, или крюк, который вызывается непосредственно перед тем, как объект запроса добавляет к нему условия? – chaseisabelle
Очень маловероятно (возможно, на самом деле я думаю), что запрос изменяется после 'hook_query_alter()' ... что, вероятно, происходит, еще один модуль также реализует 'hook_query_alter()', и его реализация выполняется только после вашего. Вы можете обойти это, реализовав ['hook_module_implements_alter()'] (https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_module_implements_alter/7) и перемещая модуль ' hook_query_alter() 'hook в конец списка – Clive
Еще раз спасибо! Я могу видеть условие, когда var_dumping объект запроса. Аргумент запроса (переданный в 'hook_query_alter') имеет тип' PagerDefault', который имеет защищенное свойство '$ query' типа' SearchQuery'. У защищенного свойства 'SearchQuery' есть массив условий, который мне нужно изменить. Есть ли способ изменить условия вложенного запроса? – chaseisabelle