Comment puis-je créer une meta_query avec un tableau comme meta_field?
-
-
Veuillez clarifier - voulez-vous dire que la * valeur stockée * de "topics"est untableau?Ou que la valeur stockéeest une chaîneet que vous souhaiteztransmettreplusieurstermes à la requête dans untableau?Please clarify--do you mean that the *stored value* of "topics" is an array? Or that the stored value is a string, and you want to pass multiple terms to the query in an array?
- 0
- 2012-06-15
- MathSmath
-
@MathSmath,je veux dire que la valeur stockéeest untableau.@MathSmath, I mean that the stored value is an array.
- 0
- 2012-06-15
- mike23
-
5 réponses
- votes
-
- 2012-06-15
Alimenter la requête d'untableau de valeurspossibles
Si la valeur de labase de donnéesest une chaîneet que vous souhaitez alimenter la requêteen plusieurs valeurs:
$args = array( 'post_type' => 'news', 'meta_query' => array( array( 'key' => 'topics', 'value' => array ( 'sports', 'nonprofit', 'community' ), 'compare' => 'IN' ) ) );
Recherche d'une valeur spécifique dans untableau de données sérialisé
Si la valeur de labase de donnéesest untableau deplusieurs rubriqueset que vous souhaitez rechercher une seule rubrique dans cetableau (notez qu'untableau de labase de donnéespeut être récupéré commetel,mais réside dans labase de données sous uneforme sérialisée,quiest également une chaîne):
$args = array( 'post_type' => 'news', 'meta_query' => array( array( 'key' => 'topics', 'value' => 'sports', 'compare' => 'LIKE' ) ) );
Utiliser 'LIKE' comme valeur de comparaisonn'estpas uneinstruction aussi claire que vous auriezpu l'espérer,mais c'est lameilleure option.
À côté de cela,votre seule autre option serait de récupérertous lesmessagespour lesquels la meta_key "topics"est définieet de lesparcourirmanuellement ou,en d'autrestermes,de vérifier la valeur dans laboucleet afficher lesmessages sur ladite condition.
Feeding the query an array of possible values
If the value in the database is a string and you want to feed the query several values:
$args = array( 'post_type' => 'news', 'meta_query' => array( array( 'key' => 'topics', 'value' => array ( 'sports', 'nonprofit', 'community' ), 'compare' => 'IN' ) ) );
Searching for a specific value in a serialized array of data
If the value in the database is an array of several topics and you want to search for a single topic within that array (Note that an array in the database can be retrieved as such, but lives in the database in serialized form, which is a string also):
$args = array( 'post_type' => 'news', 'meta_query' => array( array( 'key' => 'topics', 'value' => 'sports', 'compare' => 'LIKE' ) ) );
Using 'LIKE' as the compare value isn't as clear-cut an instruction as you might have hoped for, but it is the best option to go with.
Next to that, your only other option would be retrieving all posts that have the meta_key "topics" set and iterating over them manually or,in other words, check for the value within the loop and display the posts on said condition.
-
- 2015-06-06
Pour sortir de la réponse de Johannes,puisqu'il s'agit d'untableau sérialisé,si vous stockez quelque chose comme l'identifiant de l'utilisateur (ce qui étaitmon cas),vous devrezpeut-être legérer unpeu différemment.
Laméta dumessage a étéenregistrée comme:
array( "1", "23", "99");
Donc,oui,ce sont desentiersmais via
update_post_meta
ils étaientenregistrés sousforme de chaînes.'meta_query' => array( array( 'key' => 'my_meta_key', 'value' => serialize( strval( 1 ) ), 'compare' => 'LIKE' ) )
Vousfaites doncen fait une comparaison LIKE avec la version chaîne sérialisée de ce que vous recherchez.J'aipassé quelques heures àessayer defairefonctionner quelque chose comme çaet jusqu'àprésent,c'était lemieux queje pouvaistrouver.
To go off of Johannes' response, since it is a serialized array, if you happen to be storing something like user id's (which was my case), you may need to handle it a little differently.
Post meta was being saved like:
array( "1", "23", "99");
So yes they are integers but through
update_post_meta
they were being saved as strings.'meta_query' => array( array( 'key' => 'my_meta_key', 'value' => serialize( strval( 1 ) ), 'compare' => 'LIKE' ) )
So you're actually doing a LIKE comparison with the serialized string version of what you're looking for. I spent a good couple hours trying to get something like this to work and so far this was the best I could come up with.
-
sérialiser (strval (1)) a résolumonproblème,merciserialize(strval(1)) solved my problem, Thanks
- 0
- 2016-01-10
- Behzad
-
Je suistombé sur cette vieille réponsepar hasard aujourd'hui.J'aimeton ajout.+1Came across this old answer by chance today. I like your addition. +1
- 0
- 2016-10-20
- Johannes Pille
-
Je viens detomber sur cela aussi,montrucest queje dois obtenirtous lesmessages où user_idn'estpas dans letableau,mais la solution ci-dessusne fonctionnepas,alorsje l'aifait comme ceci: `` 'meta_query'=>tableau ( tableau ( 'key'=> 'my_meta_key', 'valeur'=> ':'.$ user_id.';', 'compare'=> 'PAS COMME' ) ) » Parce que lorsqu'elles sont sérialisées,toutes les valeurs sontenregistrées comme: ': value;'I just came across this as well, my thing is that I need to get all posts where user_id is not in array, but the above solution doesn't work so I made it like this: `'meta_query' => array( array( 'key' => 'my_meta_key', 'value' => ':' . $user_id . ';', 'compare' => 'NOT LIKE' ) )` Because when serialized all values are saved like: ':value;'
- 0
- 2018-03-19
- Bobz
-
Intelligent.Je creuse astucieux,pastoutes les approches conventionnelles.Jene m'attendaispasexactement àtrouver celaici cematin.Les accessoires.Clever. I dig nifty, not all that conventional approaches. Didn't exactly expect to find that here this morning. Props.
- 0
- 2020-08-16
- Johannes Pille
-
- 2018-07-13
Une autre légère améliorationpar rapport à la réponse de @sMyles.
J'aieu des cas où desidentifiants ont été stockés à lafois sousforme de chaînes (parexemple,lorsqu'ils sontextraits d'uneentrée deformulaire)et sousforme d'entiers (parexemple
update_post_meta($post_id, authorized_users', array(get_current_user_id()));
). C'est unpeu comme leproblèmebien connu avecwp_set_object_terms()
où vouspouvez utiliser desidentifiants determepour définir lestermes,mais si vousne les convertissezpas d'aborden entiers,vous avezenviron 50% de chances de créer denouveauxtermes avec cesnombres commenoms à laplace.Celapeutentraîner leur stockage assez différent dans untableau sérialisé,comme lemontrent lesextraits d'untel cas de labase de données demon site detest:
a:1:{i:0;s:1:"1";} // 's' for 'string', also note the double quotes a:1:{i:0;i:1;} // 'i' for 'integer', no quotes
Les deux éléments ci-dessus,lorsqu'ils sontintroduits via
print_r()
seront rendus commeArray ( [0] => 1 )
Pour résoudre ceproblème,j'ai apporté une légèremodification à la
meta_query
en ajoutant unerelation
et une autre version de la requête qui convertit la valeuren entier au lieu d'une chaîne .Voici le résultatfinal:
'meta_query' => array( 'relation' => 'OR', // Lets it know that either of the following is acceptable array( 'key' => 'bcm_enm_authorized_users', 'value' => serialize(strval(get_current_user_id())), // Saved as string 'compare' => 'LIKE' ), array( 'key' => 'bcm_enm_authorized_users', 'value' => serialize(intval(get_current_user_id())), // Saved as integer 'compare' => 'LIKE' ), ),
EDIT: Je viens deme rendre compte que cetteméthodepouvait courir le risque de collisions avec lesindex detableau,ce quipourraitpermettre à quelqu'un d'accéderillicitement auxmatériaux s'ilsne sontpas dans letableau,mais leur ID utilisateur apparaît comme Unindex. Entant quetel,bien que cela fonctionne si vous discutez duproblème,ilestpréférable de vous assurer quetoutes les valeurs que vous souhaitez rechercher sont convertiesen chaînes avant de lesenregistrer afin que vouspuissiez utiliser laméthode @sMyles à laplace.
Another slight improvement from @sMyles' answer.
I have had cases where IDs have been stored both as strings (such as when taken from a form input) and as integers (e.g.
update_post_meta($post_id, authorized_users', array(get_current_user_id()));
). This is kind of like the well-known issue withwp_set_object_terms()
where you can use term IDs to set the terms, but if you don't cast them as integers first you stand about a 50% chance of creating new terms with those numbers as their names instead.This can result in them being stored quite differently in a serialized array, as can be seen from the excerpts of just such a case from my test site's database:
a:1:{i:0;s:1:"1";} // 's' for 'string', also note the double quotes a:1:{i:0;i:1;} // 'i' for 'integer', no quotes
Both of the above, when fed through
print_r()
will render asArray ( [0] => 1 )
To fix this, I made a slight tweak to the
meta_query
by adding arelation
and another version of the query that cast the value as an integer instead of a string.Here's the final result:
'meta_query' => array( 'relation' => 'OR', // Lets it know that either of the following is acceptable array( 'key' => 'bcm_enm_authorized_users', 'value' => serialize(strval(get_current_user_id())), // Saved as string 'compare' => 'LIKE' ), array( 'key' => 'bcm_enm_authorized_users', 'value' => serialize(intval(get_current_user_id())), // Saved as integer 'compare' => 'LIKE' ), ),
EDIT: Just realized that this method could run the risk of collisions with array indexes, which could allow someone illicit access to materials if they're not in the array, but their user ID appears as an index. As such, while this works if you have the issue discussed, better practice is to ensure that any values you want to search for are cast as strings prior to saving them so that you can use @sMyles' method instead.
-
Cela devrait être la réponse choisie,laplusfiableThis should be the selected answer, most reliable
- 0
- 2019-10-23
- Amin
-
- 2016-11-02
Je choisirais la réponse de Johannes. Cependant,je souhaite améliorer cela caren utilisant cetteméta_query,vous rencontrerez un cas comme celui-ci
votre valeurest
array('sports','movies', 'sports2');
lorsque vous recherchez
$args = array( 'post_type' => 'news', 'meta_query' => array( array( 'key' => 'topics', 'value' => 'sports', 'compare' => 'LIKE' ) ) );
alors le résultat renverra à lafois "sport"et "sport2".
Pour résoudre ceproblème,changez les argumentsmeta_queryen
$args = array( 'post_type' => 'news', 'meta_query' => array( array( 'key' => 'topics', 'value' => 'sports";', 'compare' => 'LIKE' ) ) );
C'estparce que la valeurest sérialisée dans labase de données,et chaque élément sera séparépar unpoint-virgule. Ainsi,les arguments ci-dessusfonctionneront
Si les éléments de la valeur sont desnombres,il vous suffit de supprimer lesguillemets doubles "
$args = array( 'post_type' => 'news', 'meta_query' => array( array( 'key' => 'topics', 'value' => '1;', 'compare' => 'LIKE' ) ) );
I would go for Johannes's answer. However, I want to improve that because using that meta_query, you will meet a case like this
your value is
array('sports','movies', 'sports2');
when you search
$args = array( 'post_type' => 'news', 'meta_query' => array( array( 'key' => 'topics', 'value' => 'sports', 'compare' => 'LIKE' ) ) );
then the result will return both 'sport' and 'sport2'.
To fix that, change the meta_query args into
$args = array( 'post_type' => 'news', 'meta_query' => array( array( 'key' => 'topics', 'value' => 'sports";', 'compare' => 'LIKE' ) ) );
It's because the value is serialize in database, and each item will be separated by a semicolons. Thus, above args will work
If items in the value are number, you just need to remove the double quote "
$args = array( 'post_type' => 'news', 'meta_query' => array( array( 'key' => 'topics', 'value' => '1;', 'compare' => 'LIKE' ) ) );
-
- 2018-07-06
J'aitrébuché avec quelque chose de similaire aujourd'hui. Je doisinterroger un champ de relation ACF (Advanced Custom Fields) avecplusieurs utilisateurs associés (tableau).
Après avoirmis àjour le champ viaphp,la requêten'apasfonctionné.Après l'avoirmise àjour via l'interface utilisateur ACF,la requête afonctionné.
Leproblème était quemon codephp définissait les valeurs de relation sur des valeursint,l'interface utilisateur le définissait sur des valeurs de chaîne.Pourm'assurer que les deuxfonctionnent,j'utilise cette requêtemaintenant (adaptée à l'exempleici):
$args = array( 'post_type' => 'news', 'meta_query' => array( 'relation' => 'OR', array( 'key' => 'topics', 'value' => '1;', // works for int-array 'compare' => 'LIKE' ), array( 'key' => 'topics', 'value' => '"1"', // works for string-array 'compare' => 'LIKE' ), ) );
I stuggled with something similar today. I have to query a ACF (Advanced Custom Fields) relationship field with multiple related users (array).
After updating the field via php the query didn't work. After updating it via the ACF UI the query worked.
Problem was, that my php code set the relationship values to be int-values, the UI set it to string-values. To make sure both work I use this query now (fitted to the example here):
$args = array( 'post_type' => 'news', 'meta_query' => array( 'relation' => 'OR', array( 'key' => 'topics', 'value' => '1;', // works for int-array 'compare' => 'LIKE' ), array( 'key' => 'topics', 'value' => '"1"', // works for string-array 'compare' => 'LIKE' ), ) );
Voici les arguments dema requête:
Celafonctionne lorsque
topics
est une chaîne,mais pas quandil s'agit d'untableau.J'aimerais que cette requêtefonctionne lorsquetopics
estparexemplearray( 'sports', 'nonprofit', etc. )
Existe-t-il unmoyen de créer desméta-requêtes avec destableauxen tant quemeta_key?