Сортировка поиска Wordpress по релевантности
Я создал довольно расширенный поиск для сайта Wordpress, над которым я работаю в atm. Позволяет посетителям фильтровать результаты по различным таксономиям, сортировать их по дате или настраиваемым полям, а также обычный бесплатный текстовый поиск (который WP предлагает по умолчанию).
Я выполнил это, используя pre_get_posts
фильтр и просто добавив мои вещи в запрос, что-то вроде этого: (обратите внимание, что я пропустил некоторые проверки здравомыслия и другой код)
<?php
add_filter('pre_get_posts', 'my_search');
function my_search ($qry) {
# Include more post types
$qry->set('post_type', array('foo', 'bar'));
if ($_GET['myorder'] == 'price') {
$qry->set('orderby', 'meta_value_num');
$qry->set('meta_key', 'price');
$qry->set('order', 'ASC');
}
else {
$qry->set('orderby', 'date');
$qry->set('order', 'DESC');
}
}
теперь я хотел бы добавить еще один способ сортировки сообщений, а именно по релевантности. Я понимаю, что это действительно распространенный запрос, и большинство решений проблемы, которые я видел, включают использование плагина Relevanssi. Поскольку я уже написал свой собственный "плагин" (ну, по крайней мере, код) и все мои формы поиска и списки настроены на использование этого, переключение на Relevanssi не будет слишком легким на данный момент.
Sooo, я хотел бы знать, знает ли кто-нибудь о некотором (желательно) простом способе добавить это с помощью кода, который у меня уже есть получил?
насколько я понимаю, WP выполняет поиск с помощью LIKE
вместо MATCH()
и именно поэтому он даже не есть оценка релевантности для сортировки. Если это правильно, я предполагаю, что мне придется написать свой собственный запрос вообще? Как я могу это сделать, не испортив разбиение на страницы WP и т. д.? Или я могу добавить что-то вроде $qry->set('WHERE', "MATCH(post_content) AGAINST('$q' IN BOOLEAN MODE) AS relevance"); $qry->set('sortby', 'relevance')
ты думаешь?
2 ответов
Я думаю, вы можете использовать Relevanssi
без каких либо проблем, но нужно использовать filter
крюк, проверить relevanssi_modify_wp_query для получения более подробной информации проверьте следующий код
function func_reli($qry){
$qry->set( 'post_type', array( 'post', 'page', 'restaurant', 'products' ) );
if ($_GET['myorder'] == 'price') {
$qry->set('orderby', 'meta_value_num');
$qry->set('meta_key', 'price');
$qry->set('order', 'ASC');
}
else {
$qry->set('orderby', 'date');
$qry->set('order', 'DESC'); // <-- set (in your code 'add' is used)
}
return $qry; // <-- must return, in your code you didn't
}
add_filter('relevanssi_modify_wp_query', 'func_reli');
я тестировал этот код и просто отлично работает. В этом примере я использовал 'restaurant'
и 'products'
пользовательские типы сообщений и поиск работают очень хорошо, только соответствующие результаты. Вы также можете использовать if php 5.3+
установлен
add_filter('relevanssi_modify_wp_query', function($qry){
// Same code
});
кроме того, если вы используете Relevanssi плагин, вы можете использовать его настройки страницы, чтобы установить post_type
вместо этого ($qry->set( 'post_type', array(...) )
) в .
осыпь выстрел ниже
ОК, поэтому я в конечном итоге использовал Relevanssi в конце концов. Но с некоторыми изменениями.
прежде всего, фильтрация по таксономиям была довольно простой, так как это встроено в Relevanssi, все, что мне нужно было сделать, это изменить имена моих <select>
элементы в имена таксономии + измените значения на слизни:
<select name="custom_taxonomy">
<option value="some-term">Some term</option>
...
</select>
во-вторых, чтобы разрешить сортировку по пользовательскому полю, я должен был использовать relevanssi_hits_filter
фильтр. В отличие от pre_get_posts
или relevanssi_modify_wp_query
(что любезно предложил Шейх Хира), это фильтр получает переданный массив сообщений и не объект WP_Query. Когда я попытался использовать объект WP_Query, заказ просто отказался меняться. Вот в основном, как сделать свой собственный вид с relevanssi_hits_filter
:
<?php
add_filter('relevanssi_hits_filter', 'h5b_hits_filter');
function h5b_hits_filter ($hits) {
global $wp_query;
if (isset($wp_query->query_vars['orderby']) and $wp_query->query_vars['orderby'] == 'price') {
if (count($hits[0])) {
usort($hits[0], 'h5b_sort_by_price');
}
}
return $hits;
}
function h5b_sort_by_price ($a, $b) {
$priceKey = 'price';
$aPrice = get_post_meta($a->ID, $priceKey, true);
$bPrice = get_post_meta($b->ID, $priceKey, true);
$aPrice = $aPrice ? $aPrice : 10000000;
$bPrice = $bPrice ? $bPrice : 10000000;
if ($aPrice == $bPrice) {
return 0;
}
return ($aPrice < $bPrice) ? -1 : 1;
}
это также помогло с предыдущей проблемой, которую я имел в этих сообщениях, что не хватает ключ "цена"не отображается в поисках. Теперь они это делают, и причина, по которой я даю им цену "10000000", заключается в том, что они появляются после те у этого есть цена.
наконец, мне также нужно пустые поиски на работу. Согласно Relevanssi dev, это поддерживается только в премиум-версии, но я думаю, что мне удалось обойти это. Сначала я заставил WP отобразить страницу поиска, даже если ?s был пуст:
<?php
add_filter('request', 'h5b_allow_empty_search');
function h5b_allow_empty_search ($qryVars) {
if (isset($_GET['s']) and empty($_GET['s'])) {
$qryVars['s'] = ' ';
}
return $qryVars;
}
во-вторых, я сказал Relevanssi, чтобы забрать все посты, если ?s был пуст, по умолчанию он не будет получать никаких сообщений вообще. К сожалению, при этом поведение по умолчанию с пользовательскими таксономиями перестали работать (мой код написал его), поэтому мне пришлось вручную проверять таксономии в этом коде:
<?php
add_filter('relevanssi_hits_filter', 'h5b_allow_empty_search_filter');
function h5b_allow_empty_search_filter ($hits) {
if (isset($_GET['s']) and empty($_GET['s']) and !count($hits[0])) {
$taxQry = array('relation' => 'AND');
if (!empty($_GET['custom_taxonomy'])) {
$taxQry[] = array(
'taxonomy' => 'custom_taxonomy',
'field' => 'slug',
'terms' => $_GET['custom_taxonomy']
);
}
$args = array(
'numberposts' => -1,
'post_type' => 'any'
);
if (count($taxQry) > 1) {
$args['tax_query'] = $taxQry;
}
$hits[0] = get_posts($args);
}
return $hits;
}
и это все. Кажется, все работает, и, надеюсь, это поможет кому-то, у кого есть подобные запросы в будущем.
Я очень надеюсь, что WP улучшит свой нелепый поиск в будущем. Сортировка по релевантности должна быть чем-то, что доступно в самой популярной в мире CMS imo.
спасибо @Sheikh Heera за указывая мне в правильном направлении. Я не уверен, кому дать правильный ответ, хотя, видя, что я действительно не мог использовать то, что вы предложили.