J'ai modifié la recherche intégrée dans WP à l'aide du pre_get_posts
filtre, ce qui permet à l'utilisateur de trier les publications (y compris un ensemble de types de publications personnalisées) selon différents champs.
Le problème que j'ai cependant est que lorsque je dis à WP de trier par une méta-valeur, il exclut tous les posts qui n'ont pas cette méta-valeur définie. Cela entraîne le changement du nombre de résultats si vous modifiez le tri de "Prix" en "Date", car les "Messages" n'ont pas "Prix" défini mais "Articles".
Ce n'est pas ce que je veux, alors j'aimerais savoir s'il existe un moyen d'inclure TOUS les messages - même ceux qui n'ont pas la méta-valeur sur laquelle je fais le tri - et de mettre ceux qui ne le sont pas.
Je sais comment trier sur plus d'un domaine mais cela ne m'aide pas.
Merci
Il semble que je ne sois pas le seul à poser cette question: façon d’inclure des publications avec et sans certaines méta_key dans les arguments de wp_query? mais il n'y a pas de solution là-bas.
Mise à jour
J'ai essayé la réponse mais je ne suis pas sûr d'avoir bien compris. Voici ce que j'ai maintenant:
<?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');
}
La méta valeur est un nombre (il est utilisé pour stocker un prix comme son nom l'indique)
Mise à jour 2
J'ai commenté les commandes et tout ce que j'ai à présent est le suivant:
<?php
$qry->set('meta_query', array(array(
'key' => 'item_price',
'value' => '',
'compare' => 'NOT EXISTS'
)));
Avec ce code, la requête semble renvoyer toutes les publications qui ne possèdent pas la item_price
clé et aucune des publications qui en disposent. IE le problème est maintenant inversé.
Si j'ajoute également le code de commande, j'obtiens 0 résultats.
Edit: ... trois ans plus tard ... : PI avait à nouveau ce problème. J'ai essayé toutes les réponses données et aucune ne fonctionne. Je ne sais pas pourquoi certaines personnes semblent penser qu'elles travaillent mais elles ne travaillent pas pour moi du moins.
La solution avec laquelle je me suis retrouvé utilise le save_post
filtre - en s'assurant que toutes les publications ont le champ personnalisé que je souhaite trier. C'est un peu agaçant que je sois obligé de le faire, mais si vous le faites tôt, vous n'aurez probablement aucun problème.
Dans ce cas, je construisais un "compteur de vues" sur les messages et je voulais que les utilisateurs puissent trier les messages les plus lus. Encore une fois, les messages qui n’ont jamais été visionnés (je suppose que c’est assez improbable - mais qui restent) ont disparu lors du tri sur le nombre de vues. J'ai ajouté ce morceau de code pour m'assurer que toutes les publications ont un nombre de vues:
add_action('save_post', function ($postId) {
add_post_meta($postId, '_sleek_view_count', 0, true);
});
la source
meta_query
ettax_query
sont toujours unarray( array() )
car ils combinent des réseaux multiples. Deuxièmement - comme mentionné dans ma réponse - vous devez utilisermeta_value_num
pour les chiffres. Il pourrait également être nécessaire de définir réellement lemeta_value_num
(voirWP_Query
Entrée de page Codex). Enfin, il ne fait pas de sensorder
dansASC
etDESC
direction. Ce n'est pas possible. Le délimiteur d'espace ne fonctionne que pourorderby
et vous ne pouvez pas lui dire de trier le premierASC
et le secondDESC
. C'est à ça queposts_clauses
sert le filtre.meta_value_num
entrées sont de vrais nombres. Vu trop souvent, quelqu'un a dit qu'il s'agissait d'un nombre, mais l'enregistrait en fait sous forme de chaîne dans la base de données.ASC DESC
est pour qu'il trie lemeta_value
dansASC
etdate
dansDESC
, pour autant que je peux dire cela fonctionne.Réponses:
Il y a deux solutions possibles à cela:
1. Tous les messages ont méta
La meilleure solution que j'ai trouvée ici consiste à attribuer à tous les articles / produits un prix de 0. Vous pouvez le faire manuellement ou parcourir tous les articles. Si le prix est vide, mettez-le à jour.
Pour rendre cela gérable à l'avenir, vous pouvez vous accrocher
save_post
et leur donner une valeur lors de leur première addition (uniquement si elle est vide).2. Plusieurs requêtes
Vous pouvez exécuter la première requête comme vous le faites et stocker les identifiants des publications renvoyées. Vous pouvez ensuite exécuter une autre requête pour toutes les publications et toutes les commandes, en excluant les ID renvoyés par la première requête.
Vous pouvez ensuite imprimer séparément les deux résultats et vous obtiendrez les résultats souhaités.
la source
save_post
posait à nouveau: P devait utiliser la méthode (j'ai mis à jour ma question avec le code que j'ai utilisé).Easy Peasy, vient de tester 2018, en utilisant actuellement dans la production.
Ceci vérifie tous les éléments avec et sans la clé méta, sans valeur spécifiée. la méta-requête fournit la clé de la commande de manière fiable. Il a été testé. Cependant, je ne sais pas comment cela fonctionnera lorsque la méta-requête utilise plusieurs clés.
Exemple pratique
Cela classera les publications par
custom_meta_key
défaut et n'ignorera pas les publications sans valeur pour cette clé.la source
custom_meta_key
et obtenir des postes whick n'ont . N'hésitez pas à inclure un exemple de travail réel avec le tri.custom_meta_key
$query->set( 'orderby', 'meta_value title' );
(Classer par valeur méta, puis par titre lorsque plusieurs publications ont la même valeur pour la clé méta). Cela devrait être fait dans lepre_get_posts
crochet, en utilisant la$query
variable passée . Gardez à l'esprit que la question posée était comment commander par méta-valeur sans ignorer les publications qui n'ont pas de valeur pour cette méta-clé.get_posts()
appel personnalisé pour déplacer les messages avec_featured
méta vers le haut, puis ordre par date après cela. Merci!Cette méthode renverra tous les messages, y compris ceux avec et sans la demande
meta_key
, mais fera des choses étranges lors de la commande.J'ai trouvé cela en manipulant toutes les réponses différentes à cette question et en analysant le code SQL généré par essais et erreurs. Il semble que la définition des
array('meta_query' => array('relation' => 'OR'))
sorties soit appropriéeLEFT JOIN
au lieu deINNER JOIN
celle nécessaire pour inclure les publications manquant les métadonnées. La spécificationNOT EXISTS
empêche laWHERE
clause de filtrer les publications dépourvues du champ méta. Pour ce particulierWP_Query
, le SQL généré est (indentation / nouvelles lignes ajoutées):Le résultat est une liste de tous les posts avec meta_value
item_price
et de ceux qui manquentitem_price
. Tous les messages avecitem_price
seront commandés correctement par rapport à l'autre, mais les messages manquantsitem_price
utilisera une aléatoire autre valeur méta ( par exemple, ce_edit_last
qui semble être1
assez souvent dans ma base de données ou d'autres métadonnées wordpress interne qui est tout à fait arbitraire) pour sonwp_postmeta.meta_value
en laORDER BY
clause. Ainsi, alors que cette méthode est proche et peut sembler fonctionner pour certaines données, elle est cassée. Donc, tout ce que je peux dire, c'est que si vositem_price
valeurs n'entrent pas en conflit avec les champs de méta aléatoires choisis par MySQL pour les publications manquantesitem_price
, cela pourrait fonctionner correctement pour vous. Si tout ce dont vous avez besoin est une garantie que vos messages avecitem_price
sont correctement ordonnés les uns par rapport aux autres sans tenir compte de l'ordre des autres postes, cela peut aller. Mais je pense que ceci est juste une lacune dans Wordpress. S'il vous plaît, corrigez-moi, j'espère que je me trompe et qu'il existe un moyen de résoudre ce problème ;-).Il semble que pour le
INNER JOIN wp_postmeta
, MySQL choisit une ligne aléatoire parmi plusieurspostmeta
lignes associées à la publication lorsque celle-cimeta_key
est manquante. Du point de vue SQL, nous devons déterminer comment dire à wordpress de générer une sortieORDER BY mt1.meta_value
. Cette colonne est correctementNULL
lorsque notre demandemeta_key
est manquante, contrairement àwp_postmeta.meta_value
. Si nous pouvions le faire, SQL les trieraitNULL
(entrées manquantes) avant toute autre valeur, ce qui nous donnerait un ordre bien défini: tout d'abord, tous les posts manquant du champ postmeta particulier, deuxièmement, les posts ayant le champ. Mais c’est tout le problème:'orderby' => 'meta_value'
ne peut que se référer à'meta_key' => 'item_price'
et l’aliaséwp_postmeta
est toujours un,INNER JOIN
au lieu de jamais, unLEFT JOIN
senswp_postmeta.meta_value
etwp_postmeta.meta_key
peutne jamais êtreNULL
.Donc, je suppose que je dois dire que ce n'est pas possible avec le script intégré de wordpress
WP_Query
tel qu'il est maintenant documenté (dans wordpress-3.9.1). Déranger. Donc, si vous avez réellement besoin que cela fonctionne correctement, vous devrez probablement vous connecter à Wordpress ailleurs et modifier directement le code SQL généré .la source
Je pense avoir une solution.
Vous pouvez utiliser deux
meta_key
messages, un que tous les messages ont(like "_thumbnail_id")
et lemeta_key
filtre que vous souhaitez utiliser.Donc vos arguments:
la source
'value' => '',
également deuxième comparaison devrait êtreNOT EXISTS
et la dernière instruction set n'est pas nécessaireLe problème rencontré par tout le monde ici est lié à l'ordre des méta-requêtes. Pour trier correctement, vous devez placer la requête "NOT EXISTS" avant la requête "EXISTS".
La raison en est que WordPress utilise la meta_value de la dernière instruction "LEFT JOIN" dans la clause "ORDER BY".
Par exemple:
la source
Si cela convient, vous pouvez ajouter une méta-valeur par défaut chaque fois qu'une publication est enregistrée ou mise à jour, si la méta-valeur n'existe pas.
Si vous utilisez un type de message personnalisé, remplacez le
add_action('save_post', 'addDefaultMetaValue');
par, paradd_action('save_post_{post_type}', 'addDefaultMetaValue');
exempleadd_action('save_post_product', 'addDefaultMetaValue');
la source
J'ai eu le problème par moi-même pour les méta-valeurs numériques et a souligné que l'ordre de la requête est également important. Pour moi, la
NOT EXISTS
requête doit être la première.Exemple:
Il est également important de
’orderby’
définir le paramètre général pour obtenir la bonne direction pour les valeurs numériques’meta_value_num’
. Sinon, vous obtenez des résultats étranges pour les valeurs numériques, par exemple:1, 2, 20, 21, 3, 4, 5…
Au lieu de:
1, 2, 3, 4, 5… 20, 21
la source
J'ai également rencontré un problème similaire et la solution suivante m'a aidé:
J'ai trouvé une description sur WordPress Codex avec le titre " 'orderby' 'avec plusieurs' méta_key's ": https://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters
la source
Il y a une
orderby
valeur possible demeta_value
pour cela.Si vous avez des valeurs numériques, utilisez
meta_value_num
plutôt.Avertissement: Ce n'est pas testé, mais cela devrait fonctionner. Le point est que vous devez spécifier vos valeurs
meta_key
etkey
. Sinon, vous ne pouvez pas comparer des valeurs inexistantes, ce qui devrait permettre d'interroger les deux types de publication. C'est une sorte de bidouille, mais tant que ça marche ...la source
'your_keys_name'
et'your_meta_key'
si les deux doivent être la même chaîne au lieu d'être distinctes, sinon vous avez mal compris la question. Deuxièmement, j'ai testé cela sur ma configuration locale et exclut tous les posts où la clé existe (via lemeta_query
), ainsi que tous les posts où la clé est manquante (jusqu'aumeta_key
bout), ce qui entraîne l'absence d'affichage de posts. Cependant, cette réponse est un pas en avant vers quelque chose que les mots au moins ;-).'relation' => 'OR'
àmeta_query
. Wacky stuff o_o.Je pense que ce @kaiser essayait de faire était de dire la requête pour renvoyer tous les messages qui ont cette clé méta en appliquant une sorte de mannequin où la condition de ne pas filtrer l' un de ces postes. Donc, si vous savez que toutes les valeurs que vos champs personnalisés peuvent prendre sont x, y, z, vous pouvez dire "WHERE meta_key IN (x, y, z) ", mais vous pouvez éviter ce problème en disant ! = (' ') :
Également non testé, mais ça vaut le coup d'essayer :-).
la source
J'ai fini par contourner cela avec un peu de bidouille (IMHO), mais cela a fonctionné à ma place dans mon cas.
Vous pouvez vous connecter aux filtres posts_join_paged et posts_orderby pour mettre à jour les chaînes de jointure et de commande. Cela vous permettra de classer par tout ce que vous voulez, à condition que vous le rejoigniez d'abord plutôt que WP_Query en supposant que le champ doit exister pour ce poste particulier. Vous pouvez ensuite supprimer les commandes
meta_key
,orderby
et `order de vos arguments WP_Query.Ci-dessous un exemple. Au sommet de chaque fonction, je devais m'échapper pour certains cas, car cela l'ajouterait à tout ce qui utilise WP_Query. Vous devrez peut-être modifier cela pour répondre à vos besoins particuliers.
La documentation sur ces deux filtres fait cruellement défaut alors ... bonne chance! :)
la source
cast(my_custom_meta_key.meta_value as unsigned) DESC
devrait faire l'affaire ...$orderby_statement = "cast(my_custom_meta_key.meta_value as unsigned) DESC";
fonctionne très bien.Cette solution a fonctionné pour moi:
Cependant, cette solution affiche d'abord les enregistrements avec meta_value null. Cette autre solution affiche l’ordre ASC et les valeurs nulles à la fin:
la source