多个meta_query 与的参数OR
您可以使用
\'relation\' => \'OR\' 中的参数
meta_query 有两套
field_order 参数:一个
meta_value >= \'0\' 另一个是
NOT EXISTS 生成主查询。
\'meta_query\' => array(
\'relation\' => \'OR\',
field_order\' => array(
\'key\' => \'field_order\',
\'value\' => \'0\',
\'compare\' => \'>=\',
\'type\' => \'NUMERIC\'
),
\'field_order_withnulls\' => array(
\'key\' => \'field_order\',
\'compare\' => \'NOT EXISTS\',
\'type\' => \'NUMERIC\'
)
)
我们可以使用
\'field_order_withnulls\' => \'ASC\', 但是,由于左连接,将有
null field_order 值(&A);这些将出现在数字之前
field_order 中的值
ASC 订货人。
为了解决这个问题,我们将使用ORDER BY -field_order DESC 如上所述的技巧here.
这将通过反转来纠正顺序DESC 到ASC, 但保持与null 数值后的值。
实施- (反向)运算符输入orderby问题是,WordPress没有提供任何直接的方法来设置- (反向)运算符输入orderby. 因此,我们将引入一个自定义WP_Query 名为的属性_inverse_order 然后使用posts_orderby 筛选以实现它。
示例代码:
// posts_orderby filter callback function
// place this function in theme\'s functions.php file or in a custom plugin
function wpse311227_inverse_orderby( $orderby, $query ) {
remove_filter( \'posts_orderby\', \'wpse311227_inverse_orderby\', 10, 2 );
$idx = (int) $query->get( \'_inverse_order\' ) - 1;
if( $idx >= 0 ) {
$orders = preg_split( "/(?<=ASC|DESC),[\\s]*/i", $orderby );
if( $idx < count( $orders ) ) {
$orders[$idx] = \'-\' . $orders[$idx];
}
return implode( $orders, \', \' );
}
return $orderby;
}
// adding the posts_orderby filter to implement the custom \'_inverse_order\' attribute
// this should be placed just before the WP_Query call
add_filter( \'posts_orderby\', \'wpse311227_inverse_orderby\', 10, 2 );
$args = array(
\'post_type\' => \'insights\',
\'posts_per_page\' => \'9\',
\'meta_query\' => array(
\'relation\' => \'OR\',
field_order\' => array(
\'key\' => \'field_order\',
\'value\' => \'0\',
\'compare\' => \'>=\',
\'type\' => \'NUMERIC\'
),
\'field_order_withnulls\' => array(
\'key\' => \'field_order\',
\'compare\' => \'NOT EXISTS\',
\'type\' => \'NUMERIC\'
)
),
\'orderby\' => array(
\'field_order_withnulls\' => \'DESC\',
\'post_date\' => \'ASC\'
),
// this custom attribute is implemented in wpse311227_inverse_orderby() function
// to correct the ordering by placing a \'-\' operator
// value of _inverse_order attribute is the position of the
// orderby attribute to be be inversed,
// (position starts with 1)
// in this case, since: \'field_order_withnulls\' => \'DESC\'
// is in position 1 of \'orderby\' attribute array, so:
\'_inverse_order\' => 1
);
$query = new WP_Query( $args );
这将生成具有
field_order > 0 还有那些没有
field_order 具有预期顺序的元数据。
Note:您需要传递一个非空value 在里面meta_query 对于NOT EXISTS 检查WordPress版本是否低于3.9。检查此项note from codex:
由于bug#23268,在3.9之前,不存在比较需要值才能正常工作。必须为value参数提供一些字符串。空字符串或NULL无效。但是,任何其他字符串都可以做到这一点,并且在使用NOT EXISTS时不会显示在SQL中。
Warning:此
WP_Query 将使用两个
LEFT JOIN, 这不是很有效。虽然,即使是几千篇帖子,这也是可以忍受的。我已经测试了15000多篇帖子;查询平均耗时约0.3秒。然而,如果你有数百万甚至数十万篇帖子,那么你必须优化查询或找到更有效的方法来获得相同的结果。