Как сделать поиск в начале по заголовкам, а после по тексту?
Такая проблема. Сейчас сделал поиск по заголовкам среди товаров в 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... и не придётся заниматься ерундой :) Зато поимеешь кучу полезных фич.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Лучше не ломать сам поиск через
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);
Если речь именно о товарах WooCommerce, добавьте ограничение по post type в основной запрос, а не через
query_posts(). Для AJAX-поиска товаров часто быстрее и надёжнее использовать специализированный плагин или отдельный индекс поиска, потому что поиск поpost_content LIKE '%...%'на большом каталоге будет тормозить.Также не используйте устаревший
like_escape(). В современных версиях WordPress нужен$wpdb->esc_like()плюс$wpdb->prepare().