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.


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!


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


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.