He estado modificando la búsqueda de WP incorporada utilizando el pre_get_posts
filtro, lo que permite al usuario ordenar las publicaciones (incluido un montón de tipos de publicaciones personalizadas) por diferentes campos.
Sin embargo, el problema que tengo es que cuando le digo a WP que ordene por un valor meta, excluirá todas las publicaciones que no tengan ese valor meta establecido. Esto hace que cambie la cantidad de resultados si cambia la ordenación de "Precio" a "Fecha" porque "Publicaciones" no tienen "Precio" establecido, pero sí "Elementos".
Esto no es lo que quiero, así que me gustaría saber si hay una manera de incluir TODAS las publicaciones, incluso aquellas que carecen del metavalor en el que estoy clasificando, y colocar las que no tienen el último valor.
Sé cómo ordenar en más de un campo, pero eso no ayuda.
Gracias
Parece que no soy el único con esta pregunta: ¿ forma de incluir publicaciones con y sin cierta meta_key en args para wp_query? Pero no hay solución allí.
Actualizar
He intentado la respuesta pero no estoy seguro si entendí correctamente, esto es lo que tengo ahora:
<?php
function my_stuff ($qry) {
$qry->set('meta_query', array(array(
'key' => 'item_price',
'value' => '',
'compare' => 'NOT EXISTS'
)));
$qry->set('orderby', 'meta_value date'); # Sorting works with meta_value as well as meta_value_num - I've tried both
$qry->set('order', 'ASC DESC');
$qry->set('meta_key', 'item_price');
}
El metavalor es un número (se usa para almacenar un precio como sugiere su nombre)
Actualización 2
He comentado el pedido y todo lo que tengo ahora es esto:
<?php
$qry->set('meta_query', array(array(
'key' => 'item_price',
'value' => '',
'compare' => 'NOT EXISTS'
)));
Con este código, la consulta parece devolver todas las publicaciones que no tienen la item_price
clave y ninguna de las publicaciones que la tienen. Es decir, el problema ahora se invierte.
Si agrego el código de pedido también obtengo 0 resultados.
Editar: ... tres años después ... : PI tuvo este problema nuevamente. Intenté todas las respuestas dadas y ninguna funciona. No estoy seguro de por qué algunas personas parecen pensar que funcionan, pero al menos no trabajan para mí.
La solución con la que terminé es usar el save_post
filtro, asegurándome de que todas las publicaciones tengan el campo personalizado en el que deseo ordenar. Es un poco molesto que tenga que hacerlo, pero mientras lo hagas pronto es probable que no tengas problemas.
En este caso, estaba creando un "contador de vistas" en las publicaciones y quería que los usuarios pudieran ordenar las publicaciones más leídas. Una vez más, las publicaciones que nunca se han visto (supongo que es bastante improbable, pero aún así) desaparecieron al ordenar el recuento de vistas. Agregué este bit de código para asegurarme de que todas las publicaciones tengan un recuento de vistas:
add_action('save_post', function ($postId) {
add_post_meta($postId, '_sleek_view_count', 0, true);
});
fuente
meta_query
y siempretax_query
son una, ya que combinan múltiples matrices. Segundo, como se menciona en mi respuesta, debe usarlo para los números. Es posible que también sea necesario definir realmente la (consulte la entrada de la página -Codex). Por último, no tiene sentido en y dirección. Eso no es posible. El delimitador de espacio solo funciona y no puede indicarle que ordene el primero y el segundo . Para eso está el filtro.array( array() )
meta_value_num
meta_value_num
WP_Query
order
ASC
DESC
orderby
ASC
DESC
posts_clauses
meta_value_num
entradas sean números reales . Visto con demasiada frecuencia que alguien dice que es un número, pero de hecho lo guarda como una cadena en la base de datos.ASC DESC
es para que se clasifique enmeta_value
inASC
ydate
in inDESC
, por lo que puedo decir, funciona.Respuestas:
Hay dos posibles soluciones para esto:
1. Todas las publicaciones tienen meta
La mejor solución que he encontrado aquí es dar al resto de las publicaciones / productos un precio de artículo de 0. Puede hacerlo manualmente, o recorrer todas las publicaciones y si el precio está vacío, actualícelo.
Para que esto sea manejable en el futuro, puede conectarse
save_post
y darles un valor cuando se agreguen por primera vez (solo si está en blanco).2. Múltiples consultas
Puede ejecutar la primera consulta mientras lo hace y almacenar los ID de las publicaciones devueltas. Luego, podría ejecutar otra consulta para todas las publicaciones y la fecha de pedido, excluyendo los ID devueltos de la primera consulta.
A continuación, puede imprimir los dos resultados por separado y obtendrá los resultados deseados.
fuente
save_post
método (he actualizado mi pregunta con el código que usé).Easy Peasy, recién probado en 2018, actualmente en producción.
Esto verifica todos los elementos con y sin la meta clave, sin ningún valor especificado. La meta consulta proporciona la clave para el pedido de manera confiable. Ha sido probado Sin embargo, no estoy seguro de cómo funcionará cuando la metaconsulta utilice varias claves.
Ejemplo práctico
Esto ordenará las publicaciones de manera
custom_meta_key
predeterminada y no ignorará las publicaciones sin un valor para esa clave.fuente
custom_meta_key
y recibir publicaciones que no tienencustom_meta_key
. Siéntase libre de incluir un ejemplo de trabajo real con la clasificación.$query->set( 'orderby', 'meta_value title' );
(Ordenar por metavalor, luego por título cuando varias publicaciones tengan el mismo valor para la metaclave). Esto debe hacerse en elpre_get_posts
gancho, utilizando la$query
variable pasada en . Tenga en cuenta que la pregunta que se hizo fue cómo ordenar por metavalor, sin ignorar las publicaciones que no tienen un valor para esa metaclave.get_posts()
llamada personalizada para empujar publicaciones con_featured
meta a la parte superior, luego ordenar por fecha después de eso. ¡Gracias!Este método devolverá todas las publicaciones, incluidas aquellas con y sin la solicitada
meta_key
, pero hará cosas extrañas al realizar el pedido.Encontré esto jugando con todas las diferentes respuestas a esta pregunta y analizando el SQL generado a través de prueba y error. Parece que la configuración de
array('meta_query' => array('relation' => 'OR'))
un resultado apropiado enLEFT JOIN
lugar deINNER JOIN
eso es necesario para incluir publicaciones que faltan los metadatos. Especificar elNOT EXISTS
evita que laWHERE
cláusula filtre las publicaciones que carecen del metacampo. Para este particularWP_Query
, el SQL generado es (sangría / nuevas líneas agregadas):El resultado es una lista de todas las publicaciones con meta_value
item_price
y aquellas que faltanitem_price
. Todos los mensajes conitem_price
que se ordenará correctamente respecto a la otra, pero los mensajes que faltanitem_price
usará parte aleatoria otro valor meta (por ejemplo,_edit_last
que parece ser1
muy a menudo en mi base de datos o alguna otra metadatos wordpress interno que es completamente arbitraria) por suwp_postmeta.meta_value
en laORDER BY
cláusula Entonces, si bien este método está cerca y puede parecer que funciona para ciertos datos, está roto. Entonces, todo lo que puedo decir es que si susitem_price
valores no entran en conflicto con los metacampos aleatorios que MySQL elige para las publicaciones que faltanitem_price
, esto podría funcionar bien para usted. Si todo lo que necesitas es una garantía de que tus publicaciones conitem_price
están correctamente ordenados entre sí sin tener en cuenta el orden de otras publicaciones, puede estar bien. Pero creo que esto es solo una deficiencia en wordpress. Corríjame, espero estar equivocado y hay una manera de abordar esto ;-).Parece que para
INNER JOIN wp_postmeta
MySQL está eligiendo una fila aleatoria entre variaspostmeta
filas asociadas con la publicación cuandometa_key
falta en la publicación dada. Desde una perspectiva SQL, necesitamos descubrir cómo decirle a WordPress que salgaORDER BY mt1.meta_value
. Esta columna es correctaNULL
cuandometa_key
falta nuestra solicitud , a diferencia dewp_postmeta.meta_value
. Si pudiéramos hacer eso, SQL ordenaría estasNULL
(entradas faltantes) antes que cualquier otro valor, dándonos un orden bien definido: primero vienen todas las publicaciones que faltan en el campo postmeta en particular, luego vienen las publicaciones que tienen el campo. Pero ese es todo el problema:'orderby' => 'meta_value'
solo se puede referir'meta_key' => 'item_price'
y lo sin aliaswp_postmeta
siempre es un, enINNER JOIN
lugar de siempreLEFT JOIN
, un significadowp_postmeta.meta_value
ywp_postmeta.meta_key
puedenunca seNULL
.Así que supongo que tengo que decir que esto no es posible con WordPress incorporado,
WP_Query
ya que ahora está documentado (en WordPress-3.9.1). Molestia. Entonces, si realmente necesita que esto funcione correctamente, es probable que necesite conectarse a WordPress en otro lugar y modificar el SQL generado directamente .fuente
Creo que tengo una solución.
Puede usar dos
meta_key
s, uno que tienen todas las publicaciones(like "_thumbnail_id")
, y elmeta_key
que desea usar como filtro.Entonces tus argumentos:
fuente
'value' => '',
también, la segunda comparación debería serNOT EXISTS
y no se requiere la última instrucción establecidaEl problema que tienen todos aquí tiene que ver con el orden de las metaconsultas. Para ordenar correctamente, deberá colocar la consulta "NO EXISTE" antes de la consulta "EXISTA".
La razón de esto es porque WordPress usa el meta_valor de la última declaración "LEFT JOIN" en la cláusula "ORDER BY".
Por ejemplo:
fuente
Si es adecuado, puede agregar un metavalor predeterminado cada vez que se guarda o actualiza una publicación, si el metavalor no existe.
Si está utilizando un tipo de publicación personalizado, reemplácelo
add_action('save_post', 'addDefaultMetaValue');
poradd_action('save_post_{post_type}', 'addDefaultMetaValue');
ej.add_action('save_post_product', 'addDefaultMetaValue');
fuente
Tuve el problema por mí mismo para los meta valores numéricos y señalé que el orden de la consulta también es importante. Para mí, la
NOT EXISTS
consulta tiene que ser la primera.Ejemplo:
También es importante para obtener la dirección correcta para los valores numéricos el general
’orderby’
a configurar’meta_value_num’
. De lo contrario, tendrá resultados extraños para los valores numéricos, por ejemplo:1, 2, 20, 21, 3, 4, 5 ...
En lugar de:
1, 2, 3, 4, 5 ... 20, 21
fuente
También encontré un problema similar y la siguiente solución me ayudó:
Encontré una descripción en WordPress Codex con el título " 'orderby' con múltiples 'meta_key's ": https://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters
fuente
Hay un posible
orderby
valor demeta_value
eso.Si obtuvo valores numéricos, simplemente use
meta_value_num
en su lugar.Descargo de responsabilidad: esto no se ha probado, pero debería funcionar. El punto es que necesita especificar sus valores
meta_key
ykey
. De lo contrario, no se puede comparar con valores no existentes, lo que debería permitir consultar ambos tipos de publicaciones. Es una especie de hack-ish, pero mientras funcione ...fuente
'your_keys_name'
y'your_meta_key'
ambos deben ser la misma cadena en lugar de distintos, de lo contrario, parece que has entendido mal la pregunta. En segundo lugar, probé esto en mi configuración local y excluye cualquier publicación donde exista la clave (a través demeta_query
) y excluye cualquier publicación donde falta la clave (a travésmeta_key
), lo que no muestra ninguna publicación. Sin embargo, esta respuesta es un paso hacia algo que las palabras al menos ;-).'relation' => 'OR'
ameta_query
. Cosas locas o_o.Creo que lo que @kaiser intentaba hacer era decirle a la consulta que devolviera todas las publicaciones que tienen esa metaclave aplicando una especie de ficticio donde la condición de no filtrar cualquiera de esos mensajes. Entonces, si conoce todos los valores que pueden tomar sus campos personalizados son x, y, z, podría decir "WHERE meta_key IN (x, y, z) " pero la idea es que puede evitar ese problema al decir "= (' ') :
Tampoco se ha probado, pero parece que vale la pena intentarlo :-).
fuente
Terminé evitando esto con un poco de un truco (en mi humilde opinión), pero hizo el trabajo para mí en mi caso.
Puedes conectar los filtros posts_join_paged y posts_orderby para actualizar las cadenas de unión y orden. Esto le permitirá ordenar por lo que quiera siempre y cuando se una primero, en lugar de WP_Query, suponiendo que el campo debe existir para esa publicación en particular. A continuación, puede retirar el
meta_key
,orderby
y `orden de sus argumentos WP_Query.A continuación se muestra un ejemplo. En la parte superior de cada función, tuve que escapar para ciertos casos, ya que agregará esto a todo lo que use WP_Query. Es posible que deba modificarlo para que se ajuste a sus necesidades particulares.
Lamentablemente falta documentación sobre estos dos filtros, así que ... ¡buena suerte! :)
fuente
cast(my_custom_meta_key.meta_value as unsigned) DESC
debe hacer el truco ...$orderby_statement = "cast(my_custom_meta_key.meta_value as unsigned) DESC";
Funciona genial.Esta solución funcionó para mí:
Sin embargo, esta solución muestra primero los registros con meta_value nulo. Esta otra solución muestra el orden ASC y los valores nulos al final:
fuente