Consultar todas las entradas donde una meta key no existe

12 ene 2013, 18:48:33
Vistas: 109K
Votos: 70

Estoy tratando de obtener una consulta para recuperar todas las entradas donde una meta_key específica no existe y luego crearla.

Estoy teniendo problemas para encontrar esas entradas ya que la consulta que estoy probando no parece funcionar.

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

$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 entradas con la clave colors, pero devuelve los ids de las entradas con la clave colors cuando esa clave está presente (lo opuesto a lo que necesito). Intenté con EXIST en su lugar pero sin éxito.

Si alguien puede darme un consejo sobre la forma correcta de crear una consulta como la que necesito, lo agradeceré.

¡Gracias!

7
Comentarios

¿Qué versión de WordPress estás utilizando?

s_ha_dum s_ha_dum
12 ene 2013 19:10:08

Hola, disculpa por la omisión. Estoy usando la versión 3.5

JordanBel JordanBel
12 ene 2013 20:27:19

Parece que ese tipo de consulta (con compare establecido como NOT EXISTS) se agregó en la versión 3.5, por lo que debería funcionar como está, por lo que puedo ver. Aunque sería fácil hacerlo mediante una consulta SELECT personalizada...

Tomas Buteler Tomas Buteler
12 ene 2013 22:00:37

Gracias, intentaré usar select. Aunque primero debo aprender qué tablas consultar y cómo conformar la consulta :(

JordanBel JordanBel
12 ene 2013 23:08:34

Muy extraño. No puedo detectar un problema con ese código y estás usando 3.5+, por eso pregunté. ¿Has revisado realmente la base de datos para confirmar que tus datos se están insertando como crees?

s_ha_dum s_ha_dum
13 ene 2013 19:07:02

¿Has probado con 'EXISTS'? Mencionaste 'EXIST' pero creo que compare solo acepta 'EXISTS' con una 'S' al final.

mikegertrudes mikegertrudes
13 ene 2013 22:36:10

Hola, gracias. Desafortunadamente EXISTS tampoco funcionó. Creo que optaré por la opción de consulta.

JordanBel JordanBel
14 ene 2013 03:01:41
Mostrar los 2 comentarios restantes
Todas las respuestas a la pregunta 3
8
108

Hice más pruebas con esto, y honestamente no encuentro 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í sola, esta consulta meta es equivalente a "colors IS NULL", es decir, devolverá las publicaciones que no tienen esa clave establecida en la tabla postmeta. Este es el caso mostrado anteriormente, y debería haber funcionado.

'meta_query' => array(
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS' // esto debería funcionar...
    ),
)

2) Antes de WordPress 3.9, establecer el índice 'relation' como 'OR' cambia esta condición. Devuelve lo opuesto. No me preguntes por qué. Esto es especialmente importante al hacer múltiples consultas meta. Esto significa que inicialmente no es posible hacer una consulta para publicaciones que tengan la clave 'colors' establecida como 'blue' (o cualquier otro valor) o que no esté establecida en absoluto. La consulta a continuación ignorará la primera condición y solo devolverá aquellas que coincidan con la segunda condición.

'meta_query' => array(
   'relation' => 'OR',
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS' // no funciona
    ),
    array(
     'key' => 'colors',
     'value' => 'blue'
    )
)

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

'meta_query' => array(
   'relation' => 'OR',
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS', // ¡funciona!
     'value' => '' // Esto se ignora, pero es necesario...
    ),
    array(
     'key' => 'colors',
     'value' => 'blue'
    )
)

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

16 ene 2013 17:05:16
Comentarios

¡Gracias! Y disculpa por la demora. Terminé usando una consulta, pero voy a probar tu solución en las próximas horas para poder volver atrás y quizás si esto funciona podamos ayudar a otros. Te avisaré en cuanto pueda verificarlo. Gracias de nuevo

JordanBel JordanBel
17 ene 2013 03:49:32

Bien explicado y confirmado que agregar un valor vacío devuelve los resultados esperados. Diría que es no intencional, valdría la pena echar un vistazo en trac.wordpress.org para ver si ya existe un ticket, si no, esto es reproducible.

Taylor Dewey Taylor Dewey
6 mar 2013 21:22:07

Gracias por la excelente explicación y solución para engañar a WP :) Me tomó algo de tiempo llegar aquí - pero ahora quiero hacer clic en votar positivo al menos 10 veces (si tan solo pudiera ;))

lorem monkey lorem monkey
21 mar 2013 16:18:41

Si uso la comparación EXISTS, el valor desafortunadamente no se ignora en versiones más recientes de WP (probado en 4.2.2)

Igor Jerosimić Igor Jerosimić
1 jul 2015 13:08:45

¡Ten cuidado con un orderby meta_key que también pueda estar en tu consulta! WordPress codificará directamente WHERE meta_key = value para un orderby de metadatos también.

Chizzle Chizzle
8 abr 2016 06:12:57

El "error" de EXISTS y NOT EXISTS que requería especificar un valor, fue corregido en WP 3.9

trex005 trex005
15 abr 2016 10:42:22

trex005 tiene razón: "(Nota: Debido al error #23268, se requiere un valor para que las comparaciones NOT EXISTS funcionen correctamente antes de la versión 3.9. Debes proporcionar alguna cadena para el parámetro value. Una cadena vacía o NULL NO funcionará. Sin embargo, cualquier otra cadena servirá y NO aparecerá en tu SQL cuando uses NOT EXISTS. ¿Necesitas inspiración? ¿Qué tal 'bug #23268'?)"

jave.web jave.web
29 abr 2017 22:56:11

La combinación 'OR' como se mostró arriba en el punto 3) también funciona para mí, pero es muy ineficiente y resulta en tiempos de carga pesados de más de 30 segundos. (usando Woocommerce con más de 9000 productos)

Andy Tschiersch Andy Tschiersch
6 oct 2021 14:22:12
Mostrar los 3 comentarios restantes
0
20

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
            ) 
9 ene 2015 23:50:35
0

Agregar una relación hace que funcione, incluso cuando solo hay una cláusula

'meta_query' => array(
   'relation' => 'OR',
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS' 
    )
)
9 ene 2020 12:49:34