meta_query tri par 2 clés

8

J'ai besoin de trier les messages (personnalisés) par 2 valeurs de champ personnalisées ...

nom de champ personnalisé 1: is_sponsored[la valeur peut être 1ou 0]

nom de champ personnalisé 2: sfp_date[ timestampaka la date de publication actuelle en secondes]

Les messages dont la " is_sponsored" valeur est 1 doivent être en haut, triés par " sfp_date" dans l' DESCordre de fin. Tous les autres messages dont la is_sponsoredvaleur " " est 0 doivent être répertoriés ci-dessous - dans l'ordre décroissant (par " sfp_date") également.

J'ai quelque chose comme:

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

... mais ne fonctionne pas. Des idées?


Note aux rédacteurs: il s'agit d'un petit plugin qui devrait montrer à quoi ressemble la requête, car nous n'avons probablement aucun ensemble de données disponible pour tester cela.

<?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 S'IL VOUS PLAÎT AJOUTER LA SORTIE DU PLUGIN ICI - utilisez le lien "modifier" .

EDIT par Dameer

OK, après une demande de traçage et de nombreuses solutions de contournement, j'ai trouvé ce qui suit ...

Si je simplifie un peu "$ sfp_query_args", le résultat est proche de ce qui est requis, cependant, l'impossibilité de trier les messages reste telle quelle. C'est ici:

$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 prend deux attributs: meta_value et date *

Ainsi, $ wpdb-> demande avec les arguments ci-dessus dans la requête ressemble à ceci:

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

Et enfin, afin de pouvoir également trier par meta_value, la requête doit être définie avec une seule différence mineure:

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

Veuillez repérer [! ORDER MISSING!] Placeholder. Je suppose que ce qui précède devrait expliquer où exactement le problème se produit.

Dameer
la source
Je ne pense pas que vous puissiez le faire avec la classe WP_Query par défaut. Même dans les documents, il est écrit "Savez-vous comment trier la requête si la méta-valeur est un tableau? Écrivez-la ici". Vous devrez probablement écrire votre propre requête SQL pour cela.
Miha Rekar
Ouais, je sais que cela n'a pas encore été résolu mais je pensais que c'était le bon endroit pour le régler :)
Dameer
J'ai ajouté un petit plugin à votre question, afin que vous puissiez nous montrer les dernières parties de la requête SQL. Veuillez modifier votre question avec ces informations. Merci.
kaiser
Oh et voici quelques informations d'une question connexe sur le fonctionnement du tri en général.
kaiser

Réponses:

2

OK, la dernière solution consiste à fractionner la requête:

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

... et utilisez le filtre "posts_orderby" pour modifier la partie COMMANDE:

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

Le plus probablement, vous devrez supprimer le filtre après la boucle de la page afin d'éviter que 'posts_orderby' n'affecte toute autre requête (barre latérale ou pied de page). Voici donc une autre fonction à mettre dans "functions.php":

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

... et sur la page utilisant notre filtre de suppression des requêtes:

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

sfp_remove_orderby_filter();

Espérons que cela ait du sens!

Dameer
la source
-1

J'écris votre requête en modifiant légèrement. J'espère que ça peut aider.

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

Veuillez me faire savoir si cela fonctionne ou non :-)

Md Toufiqul Islam
la source
2
Ce serait le tri par défaut (par date), puisque vous ne fournissez pas 'meta_key'.
Miha Rekar
Merci @MihaRekar, ce fut une erreur merci pour votre correction
Md Toufiqul Islam
Je crains que cela ne fonctionne pas, il continue de trier les messages par date sans mettre ceux qui ont la valeur "is_sponsored" de 1 en haut.
Dameer
Je cherche à trouver une solution à cela. Peut-être que @MihaRekar a raison. Vous devrez peut-être écrire une requête SQL personnalisée pour cela
Md Toufiqul Islam
Existe-t-il un moyen de fournir un exemple de requête mySQL "normale"?
Dameer