WC_Order_Query 其中元数据不存在或不等于

问题描述

我正在尝试从数据库查询未设置自定义帖子元字段或不等于“是”的所有订单。我似乎无法让它正常工作。

我有这个:

$query = new \WC_Order_Query([
    'date_completed' => $range,'x_days_follow_up_email' => 'yes' // Note: Compares '!='
]);

然后我将它连接到 woocommerce_order_data_store_cpt_get_orders_query

if (!empty($query_vars['x_days_follow_up_email'])) {
    $query['Meta_query'][] = [
            'key' => 'x_days_follow_up_email','value' => esc_attr($query_vars['x_days_follow_up_email']),'compare' => '!='
        ]
    ];
}

return $query;

这不返回任何内容。如果我将比较更改为 ==,它会返回元设置为“是”的订单。所以我想我可能必须以某种方式包含 NOT EXISTS,如下所示:

if (!empty($query_vars['x_days_follow_up_email'])) {
    $query['Meta_query'][] = [
        'relation' => 'OR',[
            'key' => 'x_days_follow_up_email','compare' => '!='
        ],'compare' => 'NOT EXISTS'
        ]

    ];
}

return $query;

遗憾的是,这也不起作用。我可以为此编写自己的 WP_Query,但是有很多订单,我发现查询需要很长时间。我代码中的 $range 基本上是所有 11 - 8 天前的订单。而且我只想要没有元 x_days_follow_up_email 的订单,或者当元已设置但不是 yes 时。

好像应该可以吧?值得一提的是,这之前可以使用,但由于未知原因,它在更新后突然停止工作:

$query = new \WC_Order_Query([
    'date_completed' => $range,'Meta_key' => 'x_days_follow_up_email','Meta_value' => 'yes','Meta_compare' => '!='
]);

看起来很简单,但我似乎无法实现。

更新:

我也试过把它编码成普通的 WP_Query,但它达到了服务器的最大执行时间,而且效率很低:

  $args = array(
        'post_type' => 'shop_order','post_status' => 'wc-completed','posts_per_page' => -1,'Meta_query' => array(
            'relation' => 'AND',array(
                'key' => '_date_completed','value' => array($rangeStart,$rangeEnd),'compare' => 'BETWEEN','type' => 'NUMBER'
            ),array(
                'relation' => 'OR',array(
                    'key' => 'x_days_follow_up_email','value' => 'yes','compare' => '!=',),'compare' => 'NOT EXISTS',)
            )
        )
    );

解决方法

更新 - 您需要一些额外的代码来处理自定义元数据,例如:

add_filter( 'woocommerce_order_data_store_cpt_get_orders_query','order_data_store_custom_query_var',10,2 );
function order_data_store_custom_query_var( $query,$query_vars ) {
    if ( ! empty( $query_vars['xdays_fup'] ) ) {
        $query['meta_query'][] = array(
            'relation' => 'OR',array( 
                'key'     => 'x_days_follow_up_email','value'   => esc_attr( $query_vars['xdays_fup'] ),'compare' => '!=',),'compare' => 'NOT EXISTS',)
        );
    }
    return $query;
}

然后您将查询更改为:

$query = new \WC_Order_Query([
    'date_completed' => $range,'xdays_fup' => 'yes'
]);

它应该可以工作。