Consultar todas las entradas donde una meta key no existe
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!

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.

¡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

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.

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 ;))

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

¡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.

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

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'?)"
