admin管理员组

文章数量:1427361

I'm trying to fetch all my WooCommerce orders where some additional metadata is equal to not empty.

$orders = wc_get_orders( array(
    'orderby'   => 'date',
    'order'     => 'DESC',
    'meta_query' => array(
        array(
            'key' => 'var_rate',
            'compare' => 'NOT EXISTS',
        )
    )
));

So if the var_rate is empty or doesn't exist then do not return that record. At the moment all orders are returned using those arguments.

Example of empty record -

object(WC_Meta_Data)#2344 (2) {
  ["current_data":protected]=>
  array(3) {
    ["id"]=>
    int(6471)
    ["key"]=>
    string(15) "var_rate"
    ["value"]=>
    NULL
  }
  ["data":protected]=>
  array(3) {
    ["id"]=>
    int(6471)
    ["key"]=>
    string(15) "var_rate"
    ["value"]=>
    NULL
  }
}

I'm trying to fetch all my WooCommerce orders where some additional metadata is equal to not empty.

$orders = wc_get_orders( array(
    'orderby'   => 'date',
    'order'     => 'DESC',
    'meta_query' => array(
        array(
            'key' => 'var_rate',
            'compare' => 'NOT EXISTS',
        )
    )
));

So if the var_rate is empty or doesn't exist then do not return that record. At the moment all orders are returned using those arguments.

Example of empty record -

object(WC_Meta_Data)#2344 (2) {
  ["current_data":protected]=>
  array(3) {
    ["id"]=>
    int(6471)
    ["key"]=>
    string(15) "var_rate"
    ["value"]=>
    NULL
  }
  ["data":protected]=>
  array(3) {
    ["id"]=>
    int(6471)
    ["key"]=>
    string(15) "var_rate"
    ["value"]=>
    NULL
  }
}
Share Improve this question edited May 15, 2019 at 9:04 SamXronn asked May 14, 2019 at 12:02 SamXronnSamXronn 1951 gold badge3 silver badges18 bronze badges 2
  • Your code is querying all orders which do not have the metadata var_rate. So if that returns all orders, then are you sure there are actually orders having that metadata? Are you sure the name is var_rate? And to include only orders where that metadata is not empty, you should use 'compare' => '!=' and optionally add 'value' => '' to the array. – Sally CJ Commented May 14, 2019 at 13:20
  • @SallyCJ thank you for you're response checking my data an empty value is NULL. I tried as you suggested and included the following 'value' => NULL but I still get both orders. Thanks – SamXronn Commented May 14, 2019 at 13:51
Add a comment  | 

2 Answers 2

Reset to default 15

The meta_query argument (that you can use in a WP_Query) is not enabled by default when using a WC_Order_Query through wc_get_orders() WooCommerce function.

But for you can use the undocumented Custom Field Parameters (just like in a WP_Query):

  • meta_key
  • meta_value
  • meta_value_num
  • meta_compare

So in your case you can use the following instead:

$orders = wc_get_orders( array(
    'limit'        => -1, // Query all orders
    'orderby'      => 'date',
    'order'        => 'DESC',
    'meta_key'     => 'var_rate', // The postmeta key field
    'meta_compare' => 'NOT EXISTS', // The comparison argument
));

This time it works nicely (Tested on WooCommerce 3.5.8 and 3.6.2).

Apparently, WooCommerce is ignoring the meta_query parameter, so that's why you're getting all orders.

You can use this code to make the meta_query parameter works with WooCommerce (orders) queries:

add_filter( 'woocommerce_get_wp_query_args', function( $wp_query_args, $query_vars ){
    if ( isset( $query_vars['meta_query'] ) ) {
        $meta_query = isset( $wp_query_args['meta_query'] ) ? $wp_query_args['meta_query'] : [];
        $wp_query_args['meta_query'] = array_merge( $meta_query, $query_vars['meta_query'] );
    }
    return $wp_query_args;
}, 10, 2 );

But as I've pointed in my comment, to query for all orders where the var_rate metadata is not empty, set the compare to !=:

'meta_query' => array(
    array(
        'key'     => 'var_rate',
        'compare' => '!=',
        'value'   => '',
    ),
),

And in your case where you are querying with a single meta query, you could simply use the meta_key parameter along with meta_compare and meta_value, without having to use the meta_query parameter:

'meta_key'     => 'var_rate',
'meta_compare' => '!=',
'meta_value'   => '',

That way, you don't have to use the code above which "enables" the meta_query parameter.

UPDATE

I think I wasn't really paying attention to the question's title.. and I thought I should add these:

In the question's title, you got "where meta data does not exist", and for that, the 'compare' => 'NOT EXISTS' or 'meta_compare' => 'NOT EXISTS' is what you would need.

But in the question's body, you said "where some additional metadata is equal to not empty" and also "if the var_rate is empty or doesn't exist then do not return that record", and for that, the 'compare' => '!=' or 'meta_compare' => '!=' is what you would need.

Because when the compare or meta_compare is set to !=, and the value or meta_value is set to '' (the default value, if not explicitly specified), then it means, "find records where the meta exists in the database and the value is not empty (not '' or not NULL)".

I hope that helps. :)

本文标签: Query WooCommerce orders where meta data does not exist