meta_query ordenando por 2 llaves

8

Necesito ordenar las publicaciones (personalizadas) por 2 valores de campo personalizados ...

nombre de campo personalizado 1: is_sponsored[el valor puede ser 1o 0]

nombre de campo personalizado 2: sfp_date[ timestamptambién conocida como fecha de publicación actual en segundos]

Las publicaciones cuyo " is_sponsored" valor es 1 deben estar en la parte superior, ordenadas por " sfp_date" en DESCorden final. Todas las demás publicaciones cuyo " is_sponsored" valor es 0 deben aparecer a continuación, en orden descendente (por " sfp_date") también.

Tengo algo como:

$sfp_query_args = array(
    'tax_query'   => array( 
        array( 
            'taxonomy' => 'sfp_posts',
            'terms'    => array( 1, 5, 8 )
        )
    ),
    'post_type'   => 'sfpposts',
    'post_status' => 'publish',
    'showposts'   => 15,
    'paged'       => $paged,
    'meta_key'    => 'sfp_date', 
    'orderby'     => 'meta_value_num', 
    'order'       => 'DESC', 
    'meta_query'  => array(
        'key'          => 'is_sponsored',
        'value'        => 2,
        'type'         => 'NUMERIC',
        'compare'      => '<='
    )
);
$wp_q = new WP_Query( $sfp_query_args );

... pero no funciona. ¿Algunas ideas?


Nota del editor: este es un pequeño complemento que debe mostrar cómo se ve la consulta, ya que es probable que no tengamos ningún conjunto de datos disponible para probar esto.

<?php
/** Plugin Name: (#67600) Dump Query parts */
function wpse67600_dump_query_parts( $pieces )
{
    echo '<pre>'.var_export( $pieces, true ).'</pre>';
    return $pieces;
}
add_filter( 'posts_clauses', 'wpse67600_dump_query_parts' );

OP POR FAVOR AGREGUE LA SALIDA DEL PLUGIN AQUÍ - use el enlace "editar" .

EDITAR por Dameer

De acuerdo, después de la solicitud de rastreo y numerosas soluciones, se me ocurrió lo siguiente ...

Si simplifico un poco "$ sfp_query_args", el resultado está cerca de lo que se requiere, sin embargo, la incapacidad para ordenar las publicaciones permanece como está. Aquí está:

$sfp_query_args1 = array(
    'tax_query' => array( array( 'taxonomy' => 'sfp_post_category', 'terms' => $cat_id_arr ) ),
    'post_type' => 'sfpposts',
    'post_status' => 'publish',
    'showposts' => (int)$per_page,
    'paged' => $paged,
    'meta_key' => 'is_sponsored', 
    'orderby' => 'meta_value date'
);
  • * orderby toma dos atributos: meta_value y date *

Entonces $ wpdb-> request con los argumentos anteriores en la consulta se ve así:

SELECT SQL_CALC_FOUND_ROWS $wpdb->posts.ID 
FROM $wpdb->posts 
INNER JOIN $wpdb->term_relationships 
ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) 
INNER JOIN $wpdb->postmeta 
ON ($wpdb->posts.ID = $wpdb->postmeta.post_id) 
WHERE 1=1 
AND $wpdb->posts.post_type = 'sfpposts' 
AND ($wpdb->posts.post_status = 'publish') 
AND ($wpdb->postmeta.meta_key = 'is_sponsored' ) 
GROUP BY $wpdb->posts.ID 
ORDER BY $wpdb->postmeta.meta_value, $wpdb->posts.post_date DESC 
LIMIT 0, $per_page

Y finalmente, para poder ordenar también por meta_valor, la consulta debe establecerse con solo una pequeña diferencia:

SELECT SQL_CALC_FOUND_ROWS $wpdb->posts.ID 
FROM $wpdb->posts 
INNER JOIN $wpdb->term_relationships 
ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) 
INNER JOIN $wpdb->postmeta 
ON ($wpdb->posts.ID = $wpdb->postmeta.post_id) 
WHERE 1=1 
AND $wpdb->posts.post_type = 'sfpposts' 
AND ($wpdb->posts.post_status = 'publish') 
AND ($wpdb->postmeta.meta_key = 'is_sponsored' ) 
GROUP BY $wpdb->posts.ID 
ORDER BY $wpdb->postmeta.meta_value [!ORDER MISSING!], $wpdb->posts.post_date DESC 
LIMIT 0, $per_page

Por favor, identifique el marcador de posición [! ORDER MISSING!]. Supongo que lo anterior debería explicar dónde ocurre exactamente el problema.

Dameer
fuente
No creo que pueda hacer eso con la clase WP_Query predeterminada. Incluso en los documentos dice "¿Sabes cómo ordenar la consulta si el meta_valor es una matriz? Escríbelo aquí". Probablemente tendrá que escribir su propia consulta SQL para esto.
Miha Rekar
Sí, sé que aún no se ha resuelto, pero pensé que este es el lugar correcto para resolverlo :)
Dameer
He agregado un pequeño complemento a su pregunta, para que pueda mostrarnos las partes finales de la consulta SQL. Edite su pregunta con esa información. Gracias.
Kaiser
Ah, y aquí hay información de una pregunta relacionada sobre cómo funciona la clasificación en general.
Kaiser

Respuestas:

2

OK, la solución final sería dividir la consulta:

$sfp_query_args = array(
    'tax_query' => array( array( 'taxonomy' => 'sfp_post_category', 'terms' => $cat_id_arr ) ),
    'meta_key' => 'is_sponsored',
    'post_type' => 'sfpposts',
    'post_status' => 'publish',
    'showposts' => (int)$per_page,
    'paged' => $paged
);

... y use el filtro "posts_orderby" para modificar la parte ORDER:

add_filter( 'posts_orderby', 'sfp_modify_orderby' );
function sfp_modify_orderby( $orderby ) {
    if( !is_admin() && is_tax( 'sfp_post_category' ) ) {
        global $wpdb;
        $orderby = " $wpdb->postmeta.meta_value DESC, $wpdb->posts.post_date DESC ";
    }
    return $orderby;
}

Lo más probable es que necesite eliminar el filtro después del bucle en la página para evitar que 'posts_orderby' afecte a cualquier otra consulta (barra lateral o pie de página). Así que aquí hay otra función para poner en "functions.php":

function sfp_remove_orderby_filter() {
    remove_filter( 'posts_orderby', 'sfp_modify_orderby' );
}

... y en la página usando nuestro filtro de descarte de consultas:

if( have_posts() ) : while( have_posts() ) : the_post();
    // code
endwhile;
else :
    // code
endif;

sfp_remove_orderby_filter();

¡Ojalá tenga sentido!

Dameer
fuente
-1

Estoy escribiendo su consulta modificando ligeramente. Espero que pueda ayudar.

$sfp_query_args = array(
    'tax_query' => array( array( 'taxonomy' => 'sfp_posts', 'terms' => array( 1, 5, 8) ) ),
    'post_type' => 'sfpposts',
    'post_status' => 'publish',
    'showposts' => 15,
    'paged' => $paged, 
    'meta_key'=>'sfp_date', 
    'meta_query' => array(
    array(
        'key' => 'sfp_date',
            'type' => 'NUMERIC',
    ),
    array(
        'key' => 'is_sponsored',
        'value' => '2',
        'compare' => '<='
    )       
    ),
    'orderby' => 'meta_value_num', 
    'order' => 'DESC',
);
$wp_q = new WP_Query( $sfp_query_args );

Por favor, avíseme si funciona o no :-)

Md Toufiqul Islam
fuente
2
Esto ordenaría por defecto (por fecha), ya que no proporciona 'meta_key'.
Miha Rekar
Gracias @MihaRekar, fue un error gracias por su corrección
Md Toufiqul Islam
Me temo que no funciona, simplemente sigue ordenando las publicaciones por fecha sin poner a los que tienen el valor "is_spon patrocinado" 1 en la parte superior.
Dameer
Estoy buscando encontrar una solución a esto. Puede ser @MihaRekar tiene razón. Es posible que tenga que escribir una consulta SQL personalizada para esto
Md Toufiqul Islam
¿Hay alguna forma de proporcionar un ejemplo de consulta mySQL "normal"?
Dameer