为WordPress搜索构建自定义SQL查询

时间:2021-10-28 作者:Aditya Agarwal

我正在编写一个代码,在那里我使用SQL在我的网站上查找一些内容。

我意识到SQL提供了非常精确的搜索结果,并希望在我的WordPress搜索查询中实现同样的结果。

我想不出在WordPress搜索中使用SQL的方法。

下面是SQL查询:

        $Query = "SELECT SQL_CALC_FOUND_ROWS *
            FROM $wpdb->posts
            WHERE 1=1
            AND $wpdb->posts.post_status IN (\'draft\', \'publish\', \'private\', \'privatised\', \'future\', \'inherit\', \'pending\')
            AND (($wpdb->posts.post_title like \'%". $Search . "%\') OR ($wpdb->posts.post_excerpt like \'%". $Search . "%\') OR ($wpdb->posts.post_content like \'%". $Search . "%\'))
            ORDER BY    CASE ($wpdb->posts.post_title LIKE \'" . $Search . " %\') and ($wpdb->posts.post_content LIKE \'% " . $Search . " %\') WHEN 1 THEN $wpdb->posts.post_date END DESC,
                CASE ($wpdb->posts.post_title LIKE \'% " . $Search . "\') and ($wpdb->posts.post_content LIKE \'% " . $Search . " %\') WHEN 1 THEN $wpdb->posts.post_date END DESC,
                CASE ($wpdb->posts.post_title LIKE \'% " . $Search . " %\') and ($wpdb->posts.post_content LIKE \'% " . $Search . " %\') WHEN 1 THEN $wpdb->posts.post_date END DESC,
                CASE ($wpdb->posts.post_title LIKE \'% " . $Search . " %\') and ($wpdb->posts.post_content LIKE \'%" . $Search . "%\') WHEN 1 THEN $wpdb->posts.post_date END DESC, 
                CASE ($wpdb->posts.post_title LIKE \'%" . $Search . " %\') and ($wpdb->posts.post_content LIKE \'%" . $Search . " %\') WHEN 1 THEN $wpdb->posts.post_date END DESC, 
                CASE ($wpdb->posts.post_title LIKE \'%" . $Search . " %\') and ($wpdb->posts.post_content LIKE \'%" . $Search . "%\') WHEN 1 THEN $wpdb->posts.post_date END DESC, 
                CASE ($wpdb->posts.post_title LIKE \'%" . $Search . "%\') and ($wpdb->posts.post_content LIKE \'%" . $Search . " %\') WHEN 1 THEN $wpdb->posts.post_date END DESC
            LIMIT " . ($Page  -1) *     20 . ", 20 ";

    $Creations = $wpdb->get_results($Query, OBJECT);

所以,正如你所看到的,我正在使用大量的行,以便首先获得最相关的帖子。

请在我的WordPress搜索中建议一种同样的方法。

我可以找到一些现有的解决方案,可以按标题或日期进行排序,但不是按我想要的方式。

1 个回复
SO网友:Andrea Somovigo

一种可能的解决方案是使用pre_get_posts 措施:

add_action(\'pre_get_posts\', \'custom_search_query\');

function custom_search_query($query) {

  // run only if is a search query and if the search string is not empty
  if($query->is_search() && $query->is_main_query() && get_query_var(\'s\', false)) {

    // here you can use your custom query having \'get_query_var(\'s\', false)\' as $Search string
    //"SELECT SQL_CALC_FOUND_ROWS *..........
    
    // just modify your query to return only the IDS of the posts found and put them in an array $ids
    $ids=[1,2,3,4]; // example of IDS found by your custom query
    
    // unset the query_var otherwise the custom SQL will not work
    unset( $query->query_vars[\'s\'] );

    // set the IDS as \'post__in\' in the $query
    $query->set( \'post__in\', $ids );
  }
}
已移除$query->query_vars[\'s\'] 唯一缺少的是模板文件“search”中的搜索字符串。php’通常会有这样的内容:(来自TwentyTwenty1主题)

<h1 class="page-title">
<?php
printf(
    /* translators: %s: Search term. */
    esc_html__( \'Results for "%s"\', \'twentytwentyone\' ),
    \'<span class="page-description search-term">\' . esc_html( get_search_query() ) . \'</span>\'
    );
?>
</h1>
所以get_search_query() 将打印一个空字符串而不是搜索的字符串,只需替换get_search_query() 具有的函数$_GET[\'s\']