Consulta meta_query anidada con múltiples claves de relación

5 dic 2012, 22:31:45
Vistas: 91.9K
Votos: 32

Me pregunto si WordPress es capaz de ejecutar consultas meta_query anidadas, donde cada una tenga diferentes claves de relación. Desde WordPress 3.0, tax_query puede realizar esta función; me pregunto si existe un equivalente para meta_query.

$resultados = query_posts( array(
    'post_type' => 'event_id',
    'meta_query' => array(
        'relation' => 'AND',
        array(
            'relation' => 'OR',
            array(
                'key' => 'primary_user_id',
                'value' => $user_id
            ),
            array(
                'key' => 'secondary_user_id',
                'value' => $user_id
            )
        ),
        array(
            'key' => 'date',
            'value' => array( $start_date, $end_date ),
            'type' => 'DATETIME',
            'compare' => 'BETWEEN'
        )
    )
) );

Referencias:

0
Todas las respuestas a la pregunta 3
0
33

La pregunta era para WordPress 3.0, pero por si alguien tiene la misma duda para una versión más reciente, del Codex de WordPress:

"A partir de la versión 4.1, las cláusulas meta_query pueden anidarse para construir consultas complejas."

https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters Así que, esa consulta debería funcionar en la versión actual de WordPress.

19 mar 2015 20:01:46
4
18

Mientras tanto esto es posible, consulta la documentación con ejemplo y explicación:

Enlace antiguo: https://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters Actualización 2021, nuevo enlace: https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters

y otro ejemplo https://wordpress.org/support/topic/wp_query-with-multiple-meta_query/#post-9410992

'meta_query'  => array(
    'relation' => 'OR',
    array(
        'relation' => 'AND',
        array(
            'key'     => '_price',
            'value'   => 1,
            'compare' => '>=',
            'type' => 'DECIMAL',
        ),
        array(
            'key'     => '_price',
            'value' => 3000,
            'compare' => '<=',
            'type' => 'DECIMAL',
        ),
    ),
    array(
        'relation' => 'AND',
        array(
            'key'     => '_price',
            'value'   => 3001,
            'compare' => '>=',
            'type' => 'DECIMAL',
        ),
        array(
            'key'     => '_price',
            'value' => 6000, //corregido <= a =>
            'compare' => '<=',
            'type' => 'DECIMAL',
        ),
    )
),
7 ago 2018 12:34:58
Comentarios

Esta también es una buena referencia, pero agradezco la descripción completa aquí también https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters

shaneonabike shaneonabike
11 jun 2021 16:59:25

El codex.wp se está moviendo a developer.wp, así que sí, agregué la referencia correcta en su momento. En este momento, efectivamente es https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters

Ramon Fincken Ramon Fincken
15 jun 2021 15:11:52

¿Cómo agrego tres condiciones con un "AND"?

Si8 Si8
21 dic 2021 02:21:41

@Si8 un AND sería suficiente para agregar A AND B AND C. El AND está un nivel más arriba que los demás

Ramon Fincken Ramon Fincken
10 nov 2023 16:26:57
2
10

Eso parece ser imposible. Por favor, que alguien me corrija si estoy equivocado.

El parámetro meta_query en realidad se transformará en un objeto WP_Meta_Query, y la verificación de relation no profundizará más en wp-includes/meta.php, ocurriendo solo una vez en el nivel superior:

if ( isset( $meta_query['relation'] ) && strtoupper( $meta_query['relation'] ) == 'OR' ) {
    $this->relation = 'OR';
} else {
    $this->relation = 'AND';
}

Una posible solución para esto es construir tu propio JOIN para esta consulta.

$query = new WP_Query( array(
    ...
    'my_meta_query' => true,
    'suppress_filters' => false
) );

add_filter( 'posts_join', 'my_meta_query_posts_join', 10, 2 );
function my_meta_query_posts_join( $join, $query ) {

    if ( empty( $query->query_vars['my_meta_query'] ) )
        return $join;

    global $wpdb;

    $new_join = "
        INNER JOIN {$wpdb->postmeta} pm1 ON 1=1
            AND pm1.post_id = {$wpdb->posts}.ID
            AND pm1.meta_key = '_some_meta_key'
            AND pm1.meta_value = 'some_value'
    ";

    return $join . ' ' . $new_join;
}

Y si necesitas verificaciones y reglas adicionales, también puedes usar el filtro posts_where.

18 ene 2013 14:54:36
Comentarios

Parece ser el mismo enfoque que @scribu recomienda en Core Trac: https://core.trac.wordpress.org/ticket/20312

Andrew Odri Andrew Odri
29 may 2014 22:49:42

@AndrewOdri es lo mismo pero no es igual =)

vmassuchetto vmassuchetto
6 oct 2015 20:14:16