J'ai le wp_query suivant:
$args = array(
'post_type' => 'news',
'orderby' => 'meta_key',
'order' => 'ASC',
'meta_key'=>'custom_author_name',
'post_per_page'=>-1
);
$query = new WP_Query($args);
echo $query->found_posts;
echo = 10 résultats car il n'y a que 10 news
messages avec a meta_key = custom_author_name
. Mais il y a des centaines de news
publications qui n'ont pas de ligne post_meta avec cette meta_key spécifique. Veuillez noter qu'aucune méta-requête n'est impliquée. Aucune méta_value n'est affectée, car j'essaie uniquement de trier les messages par meta_key, et non de filtrer par meta_value.
Ne devrait pas commander en sélectionnant tous les messages? et juste les commander?
Si oui, pourquoi le résultat est-il filtré? Si la méta-clé n'est pas trouvée, pourquoi ne pas simplement utiliser une chaîne vide ou une correspondance avec tous?
Sinon, pourquoi pas?
Si j'entre une méta-clé dans chaque article (même s'il s'agit d'une chaîne vide), j'obtiens le résultat attendu. Mais cela semble être un tas de lignes de tableau qui n'ont pas besoin d'être là.
la source
'orderby' => 'meta_value'
, cela a changé l'ordre, mais cela n'avait rien à voir avec le champ méta réel.J'ai essayé d'appliquer la réponse de @Manny Fleurmond et comme @Jake, je n'ai pas pu le faire fonctionner même après avoir corrigé la faute de frappe qui
'orderby' => 'meta_key'
devrait être'orderby' => 'meta_value'
. (Et pour être complet, cela ne devrait'posts_per_page'
pas l' être,'post_per_page'
mais cela n'affecte pas le problème examiné.)Si vous regardez la requête SQL réellement générée par la réponse de @Manny Fleurmond (après avoir corrigé les fautes de frappe), voici ce que vous obtenez:
Cela illustre la façon dont WP analyse les variables de requête: il crée une table pour chaque clause meta_query, puis détermine comment les joindre et comment commander. La commande fonctionnerait bien si vous n'utilisiez qu'une seule clause avec
'compare' => 'EXISTS'
, mais joindre la deuxième'compare' => 'NOT EXISTS'
clause avec OR (comme nous devons) gâche la commande. Le résultat est que LEFT JOIN est utilisé pour joindre à la fois la première clause / table et la seconde clause / table - et la façon dont WP met tout ensemble signifie que la table créée à l'aide'compare' => 'EXISTS'
est réellement remplie avec des méta-valeurs de N'IMPORTE QUEL champ personnalisé, pas seulement le'custom_author_name'
champ qui nous intéresse. Je pense donc que la commande par cette clause / table ne donnera les résultats souhaités que si le post_type particulier de 'news' n'a qu'un seul champ personnalisé.La solution qui a fonctionné pour ma situation a été de commander par l'autre clause / table - celle PAS EXISTE. Apparemment contre-intuitif, je sais, mais en raison de la façon dont WP analyse les variables de requête, c'est cette table qui
meta_value
n'est remplie que par le champ personnalisé que nous recherchons.(La seule façon dont j'ai compris cela était d'exécuter l'équivalent de cette requête pour mon cas:
Tout ce que j'ai fait est de modifier les colonnes affichées et de supprimer la clause GROUP BY. Cela m'a ensuite montré ce qui se passait - que la colonne postmeta.meta_value récupérait les valeurs de toutes les méta-clés, tandis que la colonne mt1.meta_value récupérait uniquement les méta-valeurs du champ personnalisé de news.)
La solution
Comme le dit @Manny Fleurmond, c'est la première clause qui est utilisée pour la commande, donc la réponse est juste d'échanger les clauses, en donnant ceci:
Alternativement, vous pouvez rendre les clauses des tableaux associatifs et les trier par la clé correspondante, comme ceci:
la source
custom_author_name
est définie puis désactivée, celameta_key
répondraEXISTS
et l'effet sera que ceux-ci seront propagés aux côtés des messages qui ont uncustom_author_name
. Dans mon cas, j'ai une case à cocher, donc j'utilise à la"value" => "1"
place deEXISTS
, mais les chaînes auront besoin d'une approche différente.Voilà comment cela fonctionne.
Si vous souhaitez le faire sans ajouter de lignes de tableau, vous devrez effectuer deux requêtes. Un avec la meta_key qui a les résultats limités, et l'autre qui obtient la liste entière; puis utilisez PHP pour comparer les deux résultats de la requête (en supprimant éventuellement les résultats meta_key de l'autre requête pour supprimer les doublons, ou tout ce qui a du sens dans votre paramètre).
la source
Malheureusement, ce n'est pas ainsi que cela
WP_Query
fonctionne. Dès que vous ajoutez ce composant "meta", vous avez créé une sorte de filtre. Vider$query->request
et vous verrez ce que je veux dire.Deuxièmement,
WP_Query
ne prend pas du tout en charge la commande par une clé méta . Vous pouvez commander par une méta- valeur pour une clé particulière mais pas par la clé elle-même. Encore une fois, videz la requête pour voir ce que je veux dire. Vous remarquerez que les composants "commander" abandonnent si vous essayez.La façon la plus propre de faire fonctionner cela, à mon avis, est quelques filtres courts:
la source