Как сделать поиск в начале по заголовкам, а после по тексту?

Ссылка скопирована
1 ответ

Такая проблема. Сейчас сделал поиск по заголовкам среди товаров в Wordpress.

С помощью этого:

function __search_by_title_only( $search, &$wp_query ) {  global $wpdb;  if ( empty( $search ) )  return $search; // skip processing - no search term in query  $q = $wp_query->query_vars;  $n = ! empty( $q['exact'] ) ? '' : '%';  $search =  $searchand = '';  foreach ( (array) $q['search_terms'] as $term ) {  $term = esc_sql( like_escape( $term ) );  $search .= "{$searchand}($wpdb->posts.post_title LIKE '{$n}{$term}{$n}')";  $searchand = ' AND ';  }  if ( ! empty( $search ) ) {  $search = " AND ({$search}) ";  if ( ! is_user_logged_in() )  $search .= " AND ($wpdb->posts.post_password = '') ";  }  return $search; } add_filter( 'posts_search', '__search_by_title_only', 500, 2 );

function __search_by_title_only( $search, &$wp_query ) { global $wpdb; if ( empty( $search ) ) return $search; // skip processing - no search term in query $q = $wp_query->query_vars; $n = ! empty( $q['exact'] ) ? '' : '%'; $search = $searchand = ''; foreach ( (array) $q['search_terms'] as $term ) { $term = esc_sql( like_escape( $term ) ); $search .= "{$searchand}($wpdb->posts.post_title LIKE '{$n}{$term}{$n}')"; $searchand = ' AND '; } if ( ! empty( $search ) ) { $search = " AND ({$search}) "; if ( ! is_user_logged_in() ) $search .= " AND ($wpdb->posts.post_password = '') "; } return $search; } add_filter( 'posts_search', '__search_by_title_only', 500, 2 );

Как мне сделать, чтобы в первую очередь поиск был по заголовкам, а после по тексту в товарах?

Дополнительно:

Какая-то безумная идея, не имеющая никакого практического смысла.
И вообще используй https://wordpress.org/plugins/ajax-search-for-wooc... и не придётся заниматься ерундой :) Зато поимеешь кучу полезных фич.

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Никита Орлов Ответ

Лучше не ломать сам поиск через posts_search, а менять сортировку: сначала показывать совпадения в заголовке, потом совпадения в тексте. Так WordPress продолжит искать и по заголовку, и по содержимому, а вы только зададите приоритет.

Пример для обычного поиска:

add_filter('posts_orderby', function ($orderby, WP_Query $query) {
    if (is_admin() || ! $query->is_search() || ! $query->is_main_query()) {
        return $orderby;
    }
 
    global $wpdb;
    $search = $query->get('s');
 
    if ($search === '') {
        return $orderby;
    }
 
    $like = '%' . $wpdb->esc_like($search) . '%';
 
    return $wpdb->prepare(
        "CASE
            WHEN {$wpdb->posts}.post_title LIKE %s THEN 0
            WHEN {$wpdb->posts}.post_content LIKE %s THEN 1
            ELSE 2
        END, {$wpdb->posts}.post_date DESC",
        $like,
        $like
    );
}, 20, 2);

add_filter('posts_orderby', function ($orderby, WP_Query $query) { if (is_admin() || ! $query->is_search() || ! $query->is_main_query()) { return $orderby; } global $wpdb; $search = $query->get('s'); if ($search === '') { return $orderby; } $like = '%' . $wpdb->esc_like($search) . '%'; return $wpdb->prepare( "CASE WHEN {$wpdb->posts}.post_title LIKE %s THEN 0 WHEN {$wpdb->posts}.post_content LIKE %s THEN 1 ELSE 2 END, {$wpdb->posts}.post_date DESC", $like, $like ); }, 20, 2);

Если речь именно о товарах WooCommerce, добавьте ограничение по post type в основной запрос, а не через query_posts(). Для AJAX-поиска товаров часто быстрее и надёжнее использовать специализированный плагин или отдельный индекс поиска, потому что поиск по post_content LIKE '%...%' на большом каталоге будет тормозить.

Также не используйте устаревший like_escape(). В современных версиях WordPress нужен $wpdb->esc_like() плюс $wpdb->prepare().

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно