WordPress中合并多个WP_Query搜索结果的问题求助
WordPress多文章类型搜索合并结果问题
我正在开发一个WordPress项目,需要跨多种文章类型和分类法执行搜索并展示合并后的结果。我已为每种文章类型和分类法创建了独立的WP_Query对象,获取各查询返回的文章ID并合并为单个数组,但在使用合并后的ID创建最终WP_Query对象时遇到问题,无法得到预期结果。
我尝试了以下代码,但没有返回任何结果:
function data_fetch() { check_ajax_referer('data_fetch_nonce', 'security'); $keyword = isset($_POST['keyword']) ? sanitize_text_field($_POST['keyword']) : ''; $page_query = new WP_Query(array( 'fields' => 'ids', 'posts_per_page' => -1, 's' => $keyword, 'post_type' => 'page', 'post_status' => 'publish', 'tax_query' => array( array( 'taxonomy' => 'page_category', 'field' => 'slug', 'terms' => 'zabiegi', ), ), )); // Query for your custom post type $custom_post_type_query = new WP_Query(array( 'fields' => 'ids', 'posts_per_page' => -1, 's' => $keyword, 'post_type' => 'uslugi', // Replace with your custom post type slug 'post_status' => 'publish', )); // Concatenate posts arrays $combined_posts = array_merge($page_query->posts, $custom_post_type_query->posts); // Create final query $combined_results = new WP_Query(array( 'post__in' => $combined_posts, )); // Merge the results $combined_results = new WP_Query(); if ($combined_results->have_posts()) { echo '<div class="search-results">'; while ($combined_results->have_posts()) { $combined_results->the_post(); echo '<div class="search-result-item">'; echo '<div class="search-result-wrapper d-flex">'; echo '<div class="result-content">'; echo '<p class="result-title"><a class="p c-heading" href="' . esc_url(get_permalink()) . '">' . get_the_title() . '</a></p>'; echo '</div>'; echo '</div>'; echo '<div class="result-action">'; echo '<a class="result-content p c-heading f-500" href="' . esc_url(get_permalink()) . '">Przejdź' . '<svg class="result-mini-icon c-def" width="16" height="16" viewBox="0 0 16 16"> <use xlink:href="#arrow-down-tiny"></use> </svg></a>'; echo '</div>'; echo '</div>'; } echo '</div>'; wp_reset_postdata(); } else { echo '<p class="no-results">Nie znaleziono zabiegu.</p>'; } wp_die(); }
请问我哪里出错了?或者有没有更好的方法在WordPress中合并并查询多个WP_Query对象的搜索结果?
错误分析
你的代码核心问题是创建完带post__in参数的$combined_results后,又重新赋值了一个空的WP_Query对象,直接覆盖了之前的查询结果,导致后续无法获取任何内容:
// 这里已经创建了正确的查询对象 $combined_results = new WP_Query(array( 'post__in' => $combined_posts, )); // 这行代码是无结果的根本原因,清空了之前的查询 $combined_results = new WP_Query();
另外还有两个潜在问题需要处理:
- 合并ID数组时可能出现重复值,需要去重避免重复渲染结果
- 如果合并后的数组为空,
post__in会返回所有已发布文章,不符合搜索预期,需要提前判断
修复后的代码
function data_fetch() { check_ajax_referer('data_fetch_nonce', 'security'); $keyword = isset($_POST['keyword']) ? sanitize_text_field($_POST['keyword']) : ''; $page_query = new WP_Query(array( 'fields' => 'ids', 'posts_per_page' => -1, 's' => $keyword, 'post_type' => 'page', 'post_status' => 'publish', 'tax_query' => array( array( 'taxonomy' => 'page_category', 'field' => 'slug', 'terms' => 'zabiegi', ), ), )); $custom_post_type_query = new WP_Query(array( 'fields' => 'ids', 'posts_per_page' => -1, 's' => $keyword, 'post_type' => 'uslugi', 'post_status' => 'publish', )); // 合并数组并去重,重置索引避免WP_Query处理异常 $combined_posts = array_unique(array_merge($page_query->posts, $custom_post_type_query->posts)); $combined_posts = array_values($combined_posts); // 空数组直接返回无结果提示 if (empty($combined_posts)) { echo '<p class="no-results">Nie znaleziono zabiegu.</p>'; wp_die(); } // 创建最终查询,指定文章类型并保留原数组顺序 $combined_results = new WP_Query(array( 'post__in' => $combined_posts, 'post_type' => array('page', 'uslugi'), 'post_status' => 'publish', 'posts_per_page' => -1, 'orderby' => 'post__in', // 按照合并数组的顺序返回结果 )); if ($combined_results->have_posts()) { echo '<div class="search-results">'; while ($combined_results->have_posts()) { $combined_results->the_post(); echo '<div class="search-result-item">'; echo '<div class="search-result-wrapper d-flex">'; echo '<div class="result-content">'; echo '<p class="result-title"><a class="p c-heading" href="' . esc_url(get_permalink()) . '">' . get_the_title() . '</a></p>'; echo '</div>'; echo '</div>'; echo '<div class="result-action">'; echo '<a class="result-content p c-heading f-500" href="' . esc_url(get_permalink()) . '">Przejdź<svg class="result-mini-icon c-def" width="16" height="16" viewBox="0 0 16 16"><use xlink:href="#arrow-down-tiny"></use></svg></a>'; echo '</div>'; echo '</div>'; } echo '</div>'; wp_reset_postdata(); } else { echo '<p class="no-results">Nie znaleziono zabiegu.</p>'; } wp_die(); }
更优的实现方案
其实不需要多次创建WP_Query,可以直接用一个WP_Query同时查询多种文章类型,并通过tax_query的关系参数实现复杂筛选,性能更优:
function data_fetch() { check_ajax_referer('data_fetch_nonce', 'security'); $keyword = isset($_POST['keyword']) ? sanitize_text_field($_POST['keyword']) : ''; $args = array( 'posts_per_page' => -1, 's' => $keyword, 'post_type' => array('page', 'uslugi'), // 同时查询两种文章类型 'post_status' => 'publish', 'tax_query' => array( 'relation' => 'OR', // 满足任意一个条件即可 // 仅对page类型应用分类筛选 array( 'taxonomy' => 'page_category', 'field' => 'slug', 'terms' => 'zabiegi', 'post_type' => 'page' // 指定该条件仅作用于page类型 ), // 对uslugi类型设置一个始终为真的条件(无分类筛选要求) array( 'taxonomy' => 'uslugi', // 替换为uslugi对应的分类法,若无则可换成其他逻辑 'field' => 'id', 'terms' => array(0), 'operator' => 'NOT IN' ) ) ); $combined_results = new WP_Query($args); if ($combined_results->have_posts()) { echo '<div class="search-results">'; while ($combined_results->have_posts()) { $combined_results->the_post(); echo '<div class="search-result-item">'; echo '<div class="search-result-wrapper d-flex">'; echo '<div class="result-content">'; echo '<p class="result-title"><a class="p c-heading" href="' . esc_url(get_permalink()) . '">' . get_the_title() . '</a></p>'; echo '</div>'; echo '</div>'; echo '<div class="result-action">'; echo '<a class="result-content p c-heading f-500" href="' . esc_url(get_permalink()) . '">Przejdź<svg class="result-mini-icon c-def" width="16" height="16" viewBox="0 0 16 16"><use xlink:href="#arrow-down-tiny"></use></svg></a>'; echo '</div>'; echo '</div>'; } echo '</div>'; wp_reset_postdata(); } else { echo '<p class="no-results">Nie znaleziono zabiegu.</p>'; } wp_die(); }
这个方案的优势:
- 仅执行一次数据库查询,性能更高效
- 逻辑更简洁,避免数组合并和重复查询的问题
- 通过
tax_query的relation和post_type参数,精准控制不同文章类型的筛选规则
内容的提问来源于stack exchange,提问作者Pointless
相关产品推荐
相关产品推荐

