WooCommerce多术语OR关系产品查询故障排查求助
WooCommerce多术语查询OR逻辑失效问题修复
问题说明
单术语URL查询(如http://website.com/shop/?de_product_tag=test)可正常返回对应产品;但传入逗号分隔的多术语时,仅返回同时包含所有术语的产品。需要实现:URL中指定多术语时,返回包含任一术语/标签的产品。该逻辑在常规文章类型中用OR关系可正常生效,但WooCommerce中直接设置OR关系会返回全部产品,仅AND关系可用。
已配置的查询变量代码
function de_custom_query_vars_filter($vars) { // 常规分类法 $taxonomies = get_taxonomies(); foreach($taxonomies as $taxonomy) { $vars[] .= 'de_' . $taxonomy; } $vars[] .= 'de_author'; // 产品分类法 $taxonomies = get_object_taxonomies('product'); foreach($taxonomies as $taxonomy) { $vars[] .= 'de_' . $taxonomy; } return $vars; } add_filter('query_vars', 'de_custom_query_vars_filter');
原查询修改代码(存在问题)
function de_modify_woo_query($query) { if (!is_admin() && $query->is_main_query()) { $taxonomies = get_object_taxonomies('product'); $tax_query = array('relation' => 'AND'); foreach($taxonomies as $taxonomy) { if(get_query_var('de_' . $taxonomy)) { $terms = explode(',', get_query_var('de_' . $taxonomy)); foreach($terms as $term) { $tax_query[] = array( 'taxonomy' => $taxonomy, 'field' => 'slug', 'terms' => array($term), 'operator' => 'IN' ); } } } if(!empty($tax_query)) { $query->set('tax_query', $tax_query); } } } add_action('pre_get_posts', 'de_modify_woo_query');
修复方案
问题根源在于原代码将每个术语单独拆分为一个tax_query子数组,且全局关系为AND,导致必须同时满足所有术语。正确的做法是:同一分类法下的多术语放在同一个子数组中,用IN操作符实现OR逻辑;不同分类法之间保持AND关系。
修复后的代码:
function de_modify_woo_query($query) { // 仅修改前台商城主查询 if (!is_admin() && $query->is_main_query() && is_shop()) { $taxonomies = get_object_taxonomies('product'); $tax_query = array('relation' => 'AND'); foreach($taxonomies as $taxonomy) { $query_var = 'de_' . $taxonomy; if(get_query_var($query_var)) { $terms = explode(',', get_query_var($query_var)); // 同一分类法下的多术语一次性传入,IN操作符实现OR逻辑 $tax_query[] = array( 'taxonomy' => $taxonomy, 'field' => 'slug', 'terms' => $terms, 'operator' => 'IN' ); } } // 仅当存在有效分类查询时才设置,避免空查询返回全部产品 if(count($tax_query) > 1) { $query->set('tax_query', $tax_query); } } } add_action('pre_get_posts', 'de_modify_woo_query');
关键修复点
- 移除了术语循环,将同一分类法下的所有术语作为数组传入
terms参数,通过IN操作符实现该分类法内的OR逻辑(包含任一术语即匹配) - 添加
is_shop()判断,确保仅影响商城页面的主查询,避免干扰其他页面逻辑 - 增加
count($tax_query) > 1判断,防止无有效查询参数时传入空的tax_query导致返回全部产品
内容的提问来源于stack exchange,提问作者Artur B
相关产品推荐
相关产品推荐

