在 wp_query 中结合关键字搜索和税务查询

Posted

技术标签:

【中文标题】在 wp_query 中结合关键字搜索和税务查询【英文标题】:combine keyword search and tax query in wp_query 【发布时间】:2015-05-01 19:00:27 【问题描述】:

我一直在尝试创建自定义搜索查询,并且在这方面取得了一些进展,但遇到了另一个障碍。

我正在尝试将 wp_query 中的 meta_query、关键字搜索 ('s') 和 tax_query 与“OR”关系结合起来。

感谢这篇精彩的帖子,我已经让 meta_query 和 's' 一起工作: https://wordpress.stackexchange.com/questions/99849/search-that-will-look-in-custom-field-post-title-and-post-content

但是,tax_query 仍然给我带来了麻烦。我尝试通过相同的方法添加它,但似乎 wordpress 在将它输出到 SQL 查询之前对 tax_query 做了一些其他的魔法。

这是我到目前为止所得到的:

        function add_join_wpse_news($joins) 
          
            global $wpdb;
            return $joins . " INNER JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)" ;
        
        function alter_search_wpse_news($search,$qry)
        
            global $wpdb;
            $add = $wpdb->prepare("($wpdb->postmeta.meta_key = '_et_builder_settings' AND CAST($wpdb->postmeta.meta_value AS CHAR) LIKE '%%%s%%')",$qry->get('s'));
            $pat = '|\(\((.+)\)\)|';
            $search = preg_replace($pat,'(($1 OR '.$add.'))',$search);
            return $search;
        
        function alter_groupby_wpse_news($groupby)
        
            global $wpdb;

            $mygroupby = "$wpdb->posts.ID";
            if( preg_match( "/$mygroupby/", $groupby )) 
                // grouping we need is already there
                return $groupby;
            

            if( !strlen(trim($groupby))) 
                // groupby was empty, use ours
                return $mygroupby;
            

            // wasn't empty, append ours
            return $groupby . ", " . $mygroupby;
        
        add_filter('posts_join','add_join_wpse_news');
        add_filter('posts_search','alter_search_wpse_news',1,2);
        add_filter('posts_groupby', 'alter_groupby_wpse_news' );

        $args_condensed = array
        (
            'post_type' => 'news',
            'paged' => $paged,
            's' => $getname,
        );
        $the_query = new WP_Query($args_condensed);
        $max_pages = $the_query->max_num_pages;
        echo $GLOBALS['the_query']->request;

这行得通。但是,它不包括对标签或类别的搜索。我试图通过posts_join和posts_search过滤器手动添加它,但后来我意识到wordpress在输出SQL查询之前比较tax_query中的值,这在尝试添加它时会导致问题。

任何帮助将不胜感激。

编辑:为澄清起见,我正在尝试添加:

'tax_query' => array
            (
                'relation' => 'OR',
                array //Search Tag
                (
                    'taxonomy' => 'post_tag',
                    'field' => 'slug',
                    'terms' => array($getname)
                ),
                array //Search Category
                (
                    'taxonomy' => 'category',
                    'field' => 'slug',
                    'terms' => array($getname),
                ),
                array //Search Category (Single Words)
                (
                    'taxonomy' => 'category',
                    'field' => 'slug',
                    'terms' => explode(" ",$getname),
                ),
                array //Search Tag (Single Words)
                (
                    'taxonomy' => 'post_tag',
                    'field' => 'slug',
                    'terms' => explode(" ",$getname),
                )
            ),

但使用 OR 类型的关系,而不是 wordpress 默认添加的 AND 关系。

【问题讨论】:

【参考方案1】:

您无法为此目的使用 tax_query。您必须覆盖 wordpress 提供的过滤器以实现此任务。这是我的代码。希望对您有所帮助:

    function add_join_wpse_news($joins)
    
        global $wpdb;
        $joins = $joins . " INNER JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)" ;
        $joins .= " inner join  $wpdb->term_relationships  as wrel on $wpdb->posts.ID = wrel.object_id";
        $joins .= " inner join $wpdb->term_taxonomy as wtax on wtax.term_taxonomy_id = wrel.term_taxonomy_id";
        $joins .= " inner join $wpdb->terms as wter on wter.term_id = wtax.term_id";

        return $joins;

    
    function add_where_wpse_news($where) 
        $getname = 'what you want';
        return $where. ' AND '. "wter.slug like '%$getname%' ";
    
    add_filter('posts_join','add_join_wpse_news');
    add_filter('posts_where','add_where_wpse_news');

我只是添加posts_where 并修改posts_join 过滤器。

【讨论】:

这成功了!我不得不更改返回 $where。 ' 和 '。 "wter.slug like '%$getname%'";返回 $where。 ' 或者 '。 "wter.slug like '%$getname%'";但在那之后,它开始按标签拉动。极好的。现在我只需要弄清楚如何让该变量 $getname 正常工作,然后我就可以设置了。谢谢!附带说明:您知道为什么需要在此处设置 $getname 吗?我让它从 GET 的 URL 中提取,但它声称在调用此函数时它是未定义的。

以上是关于在 wp_query 中结合关键字搜索和税务查询的主要内容,如果未能解决你的问题,请参考以下文章

深入研究查询Elasticsearch,过滤查询和全文搜索

将关键字存储在查询集中,在结果查询集中提供带有 Q 对象的搜索命中以及搜索结果

将查询部分与 Lucene 和数据库中的部分(MySQL)相结合

查询ACF在自定义分类模板中的WP_Query期间发布对象

在自定义分类模板中的 WP_Query 期间查询(2)ACF 发布对象

ES DSL语法