You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过WP_Query实现WooCommerce商品标题或SKU模糊匹配查询?

WooCommerce 商品标题或SKU模糊匹配查询方案

问题说明

需要通过WP_Query实现WooCommerce商品的标题或SKU模糊匹配,比如输入timb时,匹配标题含Timber chair或SKU含M-TIMB的商品。但之前的组合参数会返回同时满足标题和SKU匹配的结果(AND逻辑),而非任一条件满足即可(OR逻辑)。

原因分析

WP_Query中,s参数(标题/内容搜索)和meta_query默认是AND关系,即使meta_query内部设置了relation => 'OR',也仅作用于meta_query组内的条件,无法改变s和meta_query之间的AND逻辑。

正确解决方案

通过WordPress的posts_join和posts_where钩子,手动构建SQL查询的OR逻辑,将标题匹配与SKU匹配的条件用OR连接:

步骤1:设置基础查询参数

$search = 'timb'; // 你的搜索关键词
$args = [
    'post_type'      => 'product',
    'post_status'    => 'publish',
    'posts_per_page' => 20,
    'fields'         => 'ids', // 仅获取ID优化性能
    'no_found_rows'  => true, // 不需要分页计数时开启,进一步优化
];

步骤2:添加钩子修改查询逻辑

add_filter('posts_join', function($join, $query) use ($search) {
    global $wpdb;
    // 仅在目标查询中执行
    if ($query->get('post_type') === 'product' && !empty($search)) {
        $join .= " LEFT JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '_sku'";
    }
    return $join;
}, 10, 2);

add_filter('posts_where', function($where, $query) use ($search) {
    global $wpdb;
    if ($query->get('post_type') === 'product' && !empty($search)) {
        // 转义关键词避免SQL注入
        $escaped_search = $wpdb->esc_like($search);
        // 构建OR条件:标题模糊匹配 或 SKU模糊匹配
        $where .= $wpdb->prepare(" AND ({$wpdb->posts}.post_title LIKE %s OR {$wpdb->postmeta}.meta_value LIKE %s)", "%{$escaped_search}%", "%{$escaped_search}%");
    }
    return $where;
}, 10, 2);

步骤3:执行查询并移除钩子

$products_query = new WP_Query($args);
$matching_product_ids = $products_query->posts;

// 移除钩子,避免影响后续其他查询
remove_filter('posts_join', '__return_empty_string');
remove_filter('posts_where', '__return_empty_string');

替代方案:用meta_query模拟标题查询

如果不想用钩子,可将标题查询转为虚拟的meta条件,再通过钩子替换为实际的post_title字段查询:

$search = 'timb';
$args = [
    'post_type'      => 'product',
    'post_status'    => 'publish',
    'posts_per_page' => 20,
    'fields'         => 'ids',
    'meta_query'     => [
        'relation' => 'OR',
        [
            'key'     => '_sku',
            'value'   => $search,
            'compare' => 'LIKE'
        ],
        [
            'key'     => 'post_title', // 虚拟key,需钩子替换
            'value'   => $search,
            'compare' => 'LIKE'
        ]
    ]
];

add_filter('posts_where', function($where) {
    global $wpdb;
    // 将meta_query中的虚拟post_title条件替换为实际字段查询
    return str_replace("{$wpdb->postmeta}.meta_key = 'post_title' AND {$wpdb->postmeta}.meta_value LIKE", "{$wpdb->posts}.post_title LIKE", $where);
});

$products_query = new WP_Query($args);
remove_filter('posts_where', '__return_empty_string');

为什么之前的方法无效?

  • 第一种组合参数:s和meta_query默认是AND关系,要求标题匹配且SKU匹配
  • 第二种修改的参数:title_filter不是WP_Query的原生参数,无法生效

内容的提问来源于stack exchange,提问作者Petras

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 05:38:22