ACF-WP_Query排序问题:先按指定值排序再按其他字段排序
问题分析
原代码的核心问题在于meta_query的OR逻辑导致排序优先级失效:event_passport别名仅对匹配event_product = 'featured'的文章生效,非推荐文章因匹配event_dates子句,无法通过该别名区分排序优先级,最终无法实现“先展示推荐文章,再展示其余文章”的效果。
解决方案
方案一:适用于所有文章均存在event_product字段的场景
直接通过meta_value排序,利用字符串排序特性让featured值优先:
$args = array( 'post_type' => 'events', 'posts_per_page' => 6, 'post_status' => 'publish', 'meta_key' => 'event_product', // 指定用于排序的meta字段 'orderby' => array( 'meta_value' => 'DESC', // 'featured'字符串会排在其他值之前 'event_dates' => 'DESC' // 同优先级内按活动日期降序 ), 'meta_query' => array( array( 'key' => 'event_dates', 'type' => 'DATETIME', 'compare' => 'EXISTS' // 确保文章包含活动日期字段 ) ) );
方案二:通用方案(支持无event_product字段的文章)
通过posts_orderby钩子自定义SQL排序逻辑,明确区分推荐与非推荐文章:
// 定义基础查询参数 $args = array( 'post_type' => 'events', 'posts_per_page' => 6, 'post_status' => 'publish', 'meta_query' => array( array( 'key' => 'event_dates', 'type' => 'DATETIME', 'compare' => 'EXISTS' ) ) ); // 添加排序钩子,仅针对当前查询生效 add_filter( 'posts_orderby', 'events_featured_first_order', 10, 2 ); function events_featured_first_order( $orderby, $query ) { global $wpdb; if ( $query->get( 'post_type' ) === 'events' && $query->get( 'posts_per_page' ) === 6 && !is_admin() ) { // 用CASE语句标记推荐文章优先级,再按活动日期排序 $orderby = " CASE WHEN {$wpdb->postmeta}.meta_key = 'event_product' AND {$wpdb->postmeta}.meta_value = 'featured' THEN 1 ELSE 0 END DESC, (SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = {$wpdb->posts}.ID AND meta_key = 'event_dates') DESC "; } return $orderby; } // 执行查询 $events_query = new WP_Query( $args ); // 移除钩子,避免影响后续其他查询 remove_filter( 'posts_orderby', 'events_featured_first_order' );
内容的提问来源于stack exchange,提问作者nsilva
相关产品推荐
相关产品推荐

