Consultar pedidos de WooCommerce donde los metadatos no existen
Estoy intentando obtener todos mis pedidos de WooCommerce donde algunos metadatos adicionales no están vacíos.
$orders = wc_get_orders( array(
'orderby' => 'date',
'order' => 'DESC',
'meta_query' => array(
array(
'key' => 'var_rate',
'compare' => 'NOT EXISTS',
)
)
));
Así que si var_rate
está vacío o no existe, no devolver ese registro. Actualmente se devuelven todos los pedidos usando estos argumentos.
Ejemplo de registro vacío -
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
}
}

El argumento meta_query
(que puedes usar en una WP_Query
) no está habilitado por defecto cuando se usa una WC_Order_Query
a través de la función wc_get_orders()
de WooCommerce.
Pero puedes usar los Custom Field Parameters no documentados (igual que en un WP_Query
):
meta_key
meta_value
meta_value_num
meta_compare
Así que en tu caso puedes usar lo siguiente:
$orders = wc_get_orders( array(
'limit' => -1, // Consultar todos los pedidos
'orderby' => 'date',
'order' => 'DESC',
'meta_key' => 'var_rate', // El campo meta_key
'meta_compare' => 'NOT EXISTS', // El argumento de comparación
));
Esta vez funciona correctamente (Probado en WooCommerce 3.5.8 y 3.6.2).

Al parecer, WooCommerce está ignorando el parámetro meta_query
, por eso estás obteniendo todos los pedidos.
Puedes usar este código para hacer que el parámetro meta_query
funcione con las consultas de WooCommerce (pedidos):
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 );
Pero como mencioné en mi comentario, para consultar todos los pedidos donde el metadato var_rate
no esté vacío, establece el compare
en !=
:
'meta_query' => array(
array(
'key' => 'var_rate',
'compare' => '!=',
'value' => '',
),
),
Y en tu caso, donde estás consultando con un solo meta query, podrías simplemente usar el parámetro meta_key
junto con meta_compare
y meta_value
, sin necesidad de usar el parámetro meta_query
:
'meta_key' => 'var_rate',
'meta_compare' => '!=',
'meta_value' => '',
De esa manera, no tienes que usar el código anterior que "habilita" el parámetro meta_query
.
ACTUALIZACIÓN
Creo que no estaba prestando suficiente atención al título de la pregunta... y pensé que debería agregar esto:
En el título de la pregunta, tienes "donde los metadatos no existen", y para eso, necesitarías 'compare' => 'NOT EXISTS'
o 'meta_compare' => 'NOT EXISTS'
.
Pero en el cuerpo de la pregunta, dijiste "donde algunos metadatos adicionales son iguales a no vacío" y también "si el var_rate
está vacío o no existe, entonces no devolver ese registro", y para eso, necesitarías 'compare' => '!='
o 'meta_compare' => '!='
.
Porque cuando compare
o meta_compare
está configurado como !=
, y value
o meta_value
está configurado como ''
(el valor predeterminado, si no se especifica explícitamente), entonces significa "encontrar registros donde el meta exista en la base de datos y el valor no esté vacío (no sea ''
o no sea NULL
)".
Espero que eso ayude. :)
