WP Meta Query中的“orderby”是否与Meta Query冲突?

时间:2014-09-12 作者:Jacktionman

我正在尝试编写一个元查询,查找下一年内开始的事件(event\\u start\\u date介于现在和52周之间)或仍在进行的事件(event\\u end\\u date介于现在和52周之间),然后通过event\\u start\\u date将它们排序到一个查询中,以生成按时间顺序排列的事件列表。

我的代码成功地查询并返回了这两个结果,但没有将它们排序在一起。它们按以下顺序显示:

9月12日9月13日9月18日9月11日至13日(结束日期)9月20日9月25日9月26日9月20日

这是我的代码:

$date_1 = date(\'Ymd\', strtotime("now"));
$date_2 = date(\'Ymd\', strtotime("52 weeks"));

$args = array(
    \'post_type\' => \'event\',
    \'order\' => \'ASC\',
    \'meta_key\' => \'event_start_date\',
    \'posts_per_page\' => 10,
    \'meta_query\' => array(
        \'relation\' => \'OR\',
        array(
            \'key\' => \'event_start_date\',
            \'value\' => array( $date_1, $date_2 ),
            \'type\' => \'numeric\',
            \'compare\' => \'BETWEEN\'
        ),
        array(
            \'key\' => \'event_end_date\',
            \'value\' => array( $date_1, $date_2 ),
            \'type\' => \'numeric\',
            \'compare\' => \'BETWEEN\'
        ),
    ),
    \'orderby\' => \'meta_value_num\'
);

$wp_query = new WP_Query( $args );

while( $wp_query->have_posts() ) {
    $wp_query->the_post();
}

1 个回复
最合适的回答,由SO网友:gmazzap 整理而成

当orderby设置为meta key时,WordPress标准查询会与多个元查询混在一起。

在经历了大量的头痛和时间浪费之后,我编写了一个自定义类,它允许我更好地处理这类事情。这里有一个我的类的简化版本,但它应该适用于您的目的:

class EventQuery {

  private $args;
  private $order;
  private $query;

  static function query( Array $args, \\WP_Query $query = NULL ) {
    if ( is_null( $query ) ) {
      $query = new \\WP_Query;
    }
    $class = __CLASS__;
    $eventquery = new $class( $args, $query );
    return $eventquery->enable()->run()->disable()->getQuery();
  }

  function __construct( Array $args, \\WP_Query $query ) {
    $this->args = $args;
    $this->order = isset( $args[\'order\'] ) && strtoupper( $args[\'order\'] === \'DESC\' )
      ? \'DESC\'
      : \'ASC\';
    $this->query = $query;
  }

  function enable() {
    add_filter( \'posts_fields_request\',  array( $this, \'filterFiels\' ) );
    add_filter( \'posts_join_request\',    array( $this, \'filterJoin\'  ) );
    add_filter( \'posts_where_request\',   array( $this, \'filterWhere\' ) );
    add_filter( \'posts_orderby_request\', array( $this, \'filterOrder\' ) );
    return $this;
  }

  function disable() {
    remove_filter( \'posts_fields_request\',  array( $this, \'filterFiels\' ) );
    remove_filter( \'posts_join_request\',    array( $this, \'filterJoin\'  ) );
    remove_filter( \'posts_where_request\',   array( $this, \'filterWhere\' ) );
    remove_filter( \'posts_orderby_request\', array( $this, \'filterOrder\' ) );
    return $this;
  }


  function filterFiels( $sql ) {
    return $sql . ", metastartdate.meta_value as start_date";
  }

  function filterJoin( $sql ) {
    global $wpdb;
    return $sql . " INNER JOIN {$wpdb->postmeta} 
        AS metastartdate ON ({$wpdb->posts}.ID = metastartdate.post_id)";
  }

  function filterWhere( $sql ) {
    return $sql . " AND metastartdate.meta_key = \'event_start_date\'";
  }

  function filterOrder( $sql ) {
    return "start_date {$this->order}";
  }

  function run() {
    $this->query->query( $this->args );
    return $this;
  }

  function getQuery() {
    return $this->query;
  }

}
可以这样使用:

$args = array (
  \'post_type\' => \'post\',
  \'posts_per_page\' => 10,
  \'meta_query\' => array(
    \'relation\' => \'OR\',
    array(
      \'key\' => \'event_start_date\',
      \'value\' => array( $date_1, $date_2 ),
      \'type\' => \'numeric\',
      \'compare\' => \'BETWEEN\'
    ),
    array(
      \'key\' => \'event_end_date\',
      \'value\' => array( $date_1, $date_2 ),
      \'type\' => \'numeric\',
      \'compare\' => \'BETWEEN\'
    ),
  ),
  \'orderby\' => \'custom\', // <-- NOTE THIS 
  \'order\' => \'ASC\'   // <-- AND THIS 
);

$query = EventQuery::query( $args ); // return a WP_Query

if ( $query->have_posts( ) ) {
  // loop here
}
当然,您可以使用“DESC”按DESC开始日期订购。

结束

相关推荐

使用新的WP-Query()从循环中过滤后期格式;

嗨,我目前正在为我的博客构建一个主题。下面的代码指向最新的帖子(特色帖子)。因为这将有一个不同的风格比所有其他职位。然而我想过滤掉帖子格式:链接使用我在循环中定义的WP查询,因为它给我带来了更多的灵活性。我该怎么做呢? <?php $featured = new WP_Query(); $featured->query(\'showposts=1\'); ?> <?php while ($featured->have_post