Je travaille sur un projet dans lequel je crée un type d'article personnalisé et des données personnalisées saisies via des méta-boîtes associées à mon type d'article personnalisé. Pour une raison quelconque, j'ai décidé de coder les boîtes de méta de manière à ce que les entrées de chaque métabox fassent partie d'un tableau. Par exemple, je stocke la longitude et la latitude:
<p>
<label for="latitude">Latitude:</label><br />
<input type="text" id="latitude" name="coordinates[latitude]" class="full-width" value="" />
</p>
<p>
<label for="longitude">Longitude:</label><br />
<input type="text" id="longitude" name="coordinates[longitude]" class="full-width" value="" />
</p>
Pour une raison quelconque, l’idée d’avoir une entrée postmeta singulière pour chaque métabox me plaisait. Sur le save_post
crochet, je sauvegarde les données comme suit:
update_post_meta($post_id, '_coordinates', $_POST['coordinates']);
Je l’ai fait parce que j’ai trois métaboxes et que j’ai envie d’avoir 3 valeurs postmeta pour chaque poste; Cependant, j'ai maintenant compris un problème potentiel avec cela. Je souhaiterai peut-être utiliser WP_Query pour extraire uniquement certains messages basés sur ces méta-valeurs. Par exemple, je souhaiterai peut-être obtenir tous les articles dont la latitude est supérieure à 50. Si j'avais ces données dans la base de données individuellement, en utilisant peut-être la clé latitude
, je ferais quelque chose comme:
$args = array(
'post_type' => 'my-post-type',
'meta_query' => array(
array(
'key' => 'latitude',
'value' => '50',
'compare' => '>'
)
)
);
$query = new WP_Query( $args );
Puisque j'ai la latitude dans le _coordinates
postmeta, cela ne fonctionnerait pas.
Ma question est donc la suivante: existe-t-il un moyen meta_query
d’interroger un tableau sérialisé comme dans ce scénario?
la source
Je cours aussi dans cette situation. Voici ce que j'ai fait:
J'espère que cette aide
la source
$value
est aussi un identifiant. Dans ce cas, je suggère de créer des fonctions pour ajouter un caractère à chaque élément du tableau avant d'enregistrer les données et une autre fonction pour supprimer le caractère avant d'utiliser les données. Ce wat, l'i:2
index sérialisé ne sera pas confondu avec lei:D2
des "vraies" données. Le paramètre de méta-requête devrait alors devenir'value' => sprintf(':"D%s";', $value),
et vous garderez la fonctionnalité correcte de cette réponse merveilleuse!LIKE
est un moyen rapide et efficace de mettre votre serveur hors service (sans parler des faux positifs), il vaut mieux avoir une très bonne mise en cache.Vous allez vraiment perdre la possibilité d'interroger vos données de manière efficace lors de la sérialisation d'entrées dans la base de données WP.
Les gains de performances globaux et les gains que vous pensez avoir obtenus grâce à la sérialisation ne seront pas remarquables dans une large mesure. Vous obtiendrez peut-être une taille de base de données légèrement inférieure, mais le coût des transactions SQL sera lourd si vous interrogez ces champs et essayez de les comparer de manière utile et significative.
Enregistrez plutôt la sérialisation pour les données que vous n'avez pas l'intention d'interroger dans cette nature, mais que vous n'accéderiez que de manière passive par l'appel direct de l'API WP
get_post_meta()
- à partir de cette fonction, vous pouvez décompresser une entrée sérialisée pour accéder également à ses propriétés de tableau.En fait assigné la valeur de true comme dans;
$meta = get_post_meta( $post->ID, 'key', true );
Renverra les données sous forme de tableau, accessible pour une itération normale.
Vous pouvez vous concentrer sur d'autres optimisations de base de données / site telles que la mise en cache, la minification CSS et JS et l'utilisation de services tels qu'un CDN, si vous en avez besoin. Pour n'en nommer que quelques-uns .... WordPress Codex est un bon point de départ pour en découvrir plus sur ce sujet: ICI
la source
Je viens de traiter des champs sérialisés et je peux les interroger. N'utilisez pas meta_query mais utilisez une requête SQL.
La requête commence par rechercher post avec le type post_type correspondant, de sorte que le nombre d'enregistrements wp_postmeta sera moins filtré. Ensuite, j'ai ajouté une instruction where pour réduire davantage les lignes en filtrant sur
meta_key
Les identifiants se retrouvent dans un tableau, comme nécessaire pour get_posts.
PS MySQL v5.6 ou supérieur est nécessaire pour obtenir de bonnes performances en sous-requête
la source
Cet exemple m'a vraiment aidé. C'est spécifiquement pour le plugin S2Members (qui sérialise les métadonnées de l'utilisateur). Mais cela vous permet d'interroger une partie d'un tableau sérialisé dans la méta_key.
Cela fonctionne en utilisant la fonction MySQL REGEXP.
Voici la source
Voici le code qui interroge tous les utilisateurs résidant aux États-Unis. Je l'ai facilement modifié pour interroger l'un de mes champs d'enregistrement personnalisés et je l'ai fait fonctionner en un rien de temps.
la source
Je pense qu'il y a deux solutions qui peuvent essayer de résoudre le problème des résultats stockés à la fois sous forme de chaîne et d'entiers. Cependant, il est important de noter, comme d'autres l'ont souligné, qu'il n'est pas possible de garantir l'intégrité des résultats stockés sous forme de nombre entier, car ces valeurs étant stockées sous forme de tableaux sérialisés, l'index et les valeurs sont stockés exactement avec le même modèle. Exemple:
est stocké comme un tableau sérialisé, comme ceci
Notez le
i:0
comme première position du tableau eti:37
comme première valeur. Le motif est le même. Mais passons aux solutions1) Solution REGEXP
Cette solution fonctionne pour moi indépendamment de la méta-valeur enregistrée en tant que chaîne ou numéro / id. Cependant, il utilise
REGEXP
, ce qui n'est pas si rapide que d'utiliserLIKE
2) comme solution
Je ne suis pas sûr de la différence de performances, mais cette solution utilise
LIKE
et fonctionne aussi bien pour les nombres que pour les chaînes.la source
REGEXP
est bien dans certaines situations, mais si vous pouvez utiliserLIKE
, je pense que c'est la méthode préférable. Un vieux lien, mais toujours utile, à mon avis: thingsilearn.wordpress.com/2008/02/28/... :-)LIKE
est plus rapide. Mais c'est une solution qui fonctionne à la fois pour les chaînes et pour les nombresLIKE
mais fonctionne à la fois pour les nombres et les chaînes. Je ne suis pas sûr de la performance car il doit comparer les résultats avecOR
Après avoir lu quelques astuces pour exécuter un
WP_Query
filtrage par des tableaux sérialisés, voici comment je l’ai finalement fait: en créant un tableau de valeurs séparées par des virgules en utilisant implode conjointement avec une$wpdb
requête SQL personnalisée utilisant laFIND_IN_SET
recherche de la valeur demandée dans la liste séparée par des virgules.(Cela ressemble à la réponse de Tomas, mais c’est un peu moins exigeant en performances pour la requête SQL)
1. Dans functions.php:
Dans votre fichier functions.php (ou partout où vous configurez la méta-boîte)
yourname_save_post()
, utilisez la fonctionpour créer le tableau contenant des valeurs séparées par des virgules.
Vous voudrez également changer votre variable de sortie dans la
yourname_post_meta()
fonction de construction de la boîte méta d’administrateur:2. Dans le fichier de modèle PHP:
Test: si vous exécutez un,
get_post_meta( $id );
vous devriez voircheckboxArray
un tableau contenant vos valeurs séparées par des virgules au lieu d’un tableau sérialisé.Maintenant, nous construisons notre requête SQL personnalisée en utilisant
$wpdb
.Remarquez le
FIND_IN_SET
, c'est là que la magie se produit.Maintenant ... depuis que je suis en utilisant
SELECT *
ceci retourne toutes les données de poste et dans leforeach
vous pouvez faire écho à ce que vous voulez que (faire unprint_r($posts);
si vous ne savez pas ce qui est inclus. Il ne définit pas « la boucle » pour vous (je le préfère de cette façon), mais il peut être facilement modifié pour mettre en place la boucle si vous préférez (regardezsetup_postdata($post);
dans le codex, vous aurez probablement besoin de changerSELECT *
pour sélectionner uniquement les identifiants de post et$wpdb->get_results
le$wpdb
type correct - - voir le codex pour$wpdb
également des informations à ce sujet).Whelp, il a fallu un peu d'effort, mais comme
wp_query
elle ne supporte pas les'compare' => 'IN'
valeurs sérialisées ou séparées par des virgules, cette cale est votre meilleure option!J'espère que ça aide quelqu'un.
la source
Si vous utilisez l'
like
opérateur de comparaison dans votre méta-requête, la recherche dans un tableau sérialisé devrait fonctionner correctement.résulte en:
la source
Si mes métadonnées sont de type tableau, j'utilise cette méthode pour les requêtes méta:
la source
Je suis curieux de connaître les réponses ci-dessus, où le
meta_query
ciblé la clélatitude
au lieu de_coordinates
. Nous devions vérifier si les méta-requêtes permettaient de cibler une clé spécifique dans un tableau sérialisé. :)Ce n'était évidemment pas le cas.
Donc, notez que la clé correcte à cibler est
_coordinates
au lieu delatitude
.REMARQUES:
Cette approche permet uniquement de cibler des correspondances exactes. Des choses comme toutes les latitudes supérieures à 50 ne sont pas possibles.
Pour inclure des correspondances de sous-chaîne, on pourrait utiliser
'value' => sprintf(':"%%%s%%";', $value),
. (n'a pas testé)la source
J'ai la même question. Peut-être avez-vous besoin du paramètre 'type'? Consultez cette question connexe: Requête de champ personnalisé - La méta-valeur est un tableau
Peut-être essayer:
la source
J'ai rencontré quelque chose de similaire en utilisant le plugin Magic Fields. Cela pourrait faire l'affaire
la source
serialize()
n'est pas nécessaire dans ce cas ...