使用SearchWP时,如何通过钩子在$swp_query返回前过滤结果仅保留父文章?
问题
我正在开发一款自定义WordPress主题,使用SearchWP实现文章归档搜索功能。已配置SearchWP使其同时检索文章内容及文章附带的PDF文档,但目前存在一个问题:部分搜索结果中会同时显示PDF附件与其父文章作为独立条目,我仅希望父文章出现在搜索结果里。
我已编写好过滤逻辑用于保留父文章并去除重复项,但需要将过滤后的结果存入$swp_query对象中,以确保$swp_query->found_posts和$swp_query->post_count的数值准确。请问是否有合适的SearchWP钩子,可在初始$swp_query返回前执行该过滤操作?
当前使用的过滤逻辑代码:
if (isset($swp_query) && !empty($swp_query->have_posts())) { $filtered_posts = array(); foreach ($swp_query->posts as $post) { $is_attachment = (get_post_type($post) === 'attachment'); $post_id = $is_attachment ? wp_get_post_parent_id($post->ID) : $post->ID; $is_duplicate = false; foreach ($filtered_posts as $filtered_post) { if ($filtered_post->ID === $post_id) { $is_duplicate = true; break; } } if (!$is_duplicate) { $filtered_posts[] = $is_attachment ? get_post($post_id) : $post; } } }
解决方案
你可以使用SearchWP提供的searchwp\query\posts钩子,该钩子会在SearchWP完成查询、准备返回结果前触发,正好适合用来修改$swp_query的文章列表及计数属性。
实现代码
add_filter('searchwp\query\posts', function($posts, $query) { $filtered_posts = array(); $seen_post_ids = array(); // 用数组记录已处理的文章ID,提升去重效率 foreach ($posts as $post) { $is_attachment = get_post_type($post) === 'attachment'; $target_post_id = $is_attachment ? wp_get_post_parent_id($post->ID) : $post->ID; // 跳过无有效父文章的附件 if ($is_attachment && empty($target_post_id)) { continue; } // 仅添加未出现过的目标文章 if (!in_array($target_post_id, $seen_post_ids)) { $seen_post_ids[] = $target_post_id; $filtered_posts[] = $is_attachment ? get_post($target_post_id) : $post; } } // 更新查询对象的核心属性 $query->posts = $filtered_posts; $query->post_count = count($filtered_posts); $query->found_posts = count($filtered_posts); // 若需更精准的总匹配数,可根据实际场景调整 return $filtered_posts; }, 10, 2);
关键说明
- 钩子优先级设为10(默认值),回调函数接收两个参数:
$posts为原始搜索结果数组,$query即你需要修改的$swp_query对象。 - 将原嵌套循环的去重逻辑改为数组查询,大幅提升处理效率,尤其在搜索结果较多时更明显。
- 增加了对无父文章附件的过滤,避免无效内容混入结果。
- 直接修改
$query的posts、post_count、found_posts属性后,后续调用这些属性时就能得到过滤后的准确数值。
内容的提问来源于stack exchange,提问作者AWilford
相关产品推荐
相关产品推荐

