Consultar todas las publicaciones donde no existe una metaclave

50

Estoy tratando de obtener una consulta para recuperar todas las publicaciones donde meta_keyno existe un específico y luego crearlo.

Tengo problemas para encontrar esas publicaciones ya que la consulta que estoy probando no parece funcionar.

Aquí está el código que estoy usando para intentar obtener esas publicaciones:

$args = array(
   'posts_per_page' => 18,
   'cat'=>1955,
   'post_status'=>'publish',
   'meta_query' => array(
                  array(
                     'key' => 'colors',
                     'compare' => 'NOT EXISTS'
                  ),
   ));      

query_posts($args);

Esto no devuelve nada si no hay publicaciones con la clave colors, pero las devuelve idsde las publicaciones con la clave colorssiempre que esa clave esté presente (lo contrario de lo que necesito). Lo intenté con, EXISTpero no tuve suerte.

Si alguien me puede aconsejar sobre la forma correcta de crear una consulta como la que necesito, lo agradeceré.

¡Gracias!

JordanBel
fuente
¿Qué versión de WordPress estás usando?
s_ha_dum
Hola, perdón por la omisión. Estoy usando v3.5
JordanBel
Parece que ese tipo de consulta (con el conjunto de comparación a NO EXISTE) se agregó en 3.5, por lo que debería funcionar como es, hasta donde puedo ver. Sin embargo, sería fácil hacerlo a través de una consulta SELECT personalizada ...
Tomas Buteler
Gracias, intentaré usar select. Debo saber antes qué tablas consultar y cómo conformar la consulta :(
JordanBel
Muy extraño. No puedo detectar un problema con ese código y está utilizando 3.5+, por eso le pregunté. ¿Realmente has mirado la base de datos para confirmar que tus datos se están insertando de la manera que crees?
s_ha_dum

Respuestas:

73

Hice algunas pruebas más con esto, y honestamente no puedo encontrar una razón por la que no funcionaría (a menos que el código anterior sea solo un fragmento y el código real se ajuste a mis ejemplos a continuación). Sin embargo, descubrí un par de cosas que podrían guiarte en la dirección correcta.

1) Por sí misma, esta metaconsulta es el equivalente de "colors IS NULL", es decir, devolverá las publicaciones que no tienen esa clave establecida en la tabla postmeta. Este es el caso que se muestra arriba, y debería haber funcionado.

'meta_query' => array(
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS' // this should work...
    ),
)

2) Antes de WordPress 3.9, establecer el índice de 'relación' a 'O' cambia esta condición. Devuelve lo contrario. No me preguntes por qué. Esto es especialmente importante cuando se realizan múltiples metaconsultas. Eso significa que inicialmente no es posible hacer una consulta para publicaciones que tienen la tecla 'colores' configurada en 'azul' (o lo que sea) o que no están configuradas en absoluto. La consulta a continuación ignorará la primera condición y devolverá solo las que coincidan con la segunda condición.

'meta_query' => array(
   'relation' => 'OR',
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS' // doesn't work
    ),
    array(
     'key' => 'colors',
     'value' => 'blue'
    )
)

3) Sin embargo, podemos engañar a WordPress para que use la primera condición si establecemos el 'valor'. No necesita un valor relevante (por lo que sé, se ignora), pero debe establecerse para que la NOT EXISTScondición tenga algún efecto.

'meta_query' => array(
   'relation' => 'OR',
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS', // works!
     'value' => '' // This is ignored, but is necessary...
    ),
    array(
     'key' => 'colors',
     'value' => 'blue'
    )
)

Esto fue cierto hasta WordPress 3.9. Si todavía está utilizando una versión anterior, esta es una solución viable.

Tomás Buteler
fuente
¡Gracias! Y perdón por el retraso. Terminé usando una consulta, pero probaré su solución en las siguientes horas para poder cambiar y tal vez si este trabajo podamos ayudar a otros. Te lo haré saber tan pronto como pueda comprobarlo. Gracias de nuevo
JordanBel
Bien escrito y confirmado que agregar un valor vacío devuelve los resultados esperados. Diría que no es intencional, vale la pena echarle un vistazo a trac.wordpress.org para ver si ya hay un boleto, si no, esto es reproducible.
Taylor Dewey
Gracias por la gran explicación y solución para engañar a WP :) Tomé un tiempo para llegar aquí, pero ahora quiero hacer clic en votar por al menos 10 veces (si solo pudiera;))
lorem monkey
Si uso compare EXISTS, desafortunadamente el valor no se ignora en las versiones más recientes de WP (probado en 4.2.2)
Igor Jerosimić
10
El EXISTSy el NOT EXISTS"error" que requería que especificaras un valor, se corrigió en WP 3.9
trex005
11

Usando una consulta personalizada, esto funcionó para mí:

SELECT * FROM wp_posts as posts
            WHERE   posts.post_type     = 'post'
            AND NOT EXISTS (
              SELECT * FROM `wp_postmeta`
               WHERE `wp_postmeta`.`meta_key` = "your_meta_key"
                AND `wp_postmeta`.`post_id`=posts.ID
            ) 
I a
fuente