Ich arbeite an einem Projekt, in dem ich einen benutzerdefinierten Beitragstyp erstelle und benutzerdefinierte Daten über Metafelder eingebe, die meinem benutzerdefinierten Beitragstyp zugeordnet sind. Aus irgendeinem Grund habe ich beschlossen, die Meta-Boxen so zu codieren, dass die Eingaben in jeder Metabox Teil eines Arrays sind. Zum Beispiel speichere ich Längen- und Breitengrade:
<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>
Aus irgendeinem Grund gefiel mir die Idee, für jede Metabox einen eigenen Postmeta-Eintrag zu haben. Am save_post
Haken speichere ich die Daten so:
update_post_meta($post_id, '_coordinates', $_POST['coordinates']);
Ich habe das gemacht, weil ich drei Metaboxen habe und ich mag es, nur 3 Postmeta-Werte für jeden Post zu haben. Allerdings habe ich jetzt ein potenzielles Problem damit erkannt. Ich möchte möglicherweise WP_Query verwenden, um nur bestimmte Beiträge basierend auf diesen Metawerten abzurufen. Zum Beispiel möchte ich möglicherweise alle Posts mit Breitengraden über 50 erhalten. Wenn ich diese Daten einzeln in der Datenbank hätte, vielleicht mithilfe des Schlüssels latitude
, würde ich Folgendes tun:
$args = array(
'post_type' => 'my-post-type',
'meta_query' => array(
array(
'key' => 'latitude',
'value' => '50',
'compare' => '>'
)
)
);
$query = new WP_Query( $args );
Da ich den Breitengrad als Teil der _coordinates
Postmeta habe, würde dies nicht funktionieren.
Meine Frage ist also, gibt es eine Möglichkeit, meta_query
ein serialisiertes Array wie in diesem Szenario abzufragen?
quelle
Ich stoße auch auf diese Situation. Hier was ich getan habe:
Ich hoffe das hilft
quelle
$value
es sich auch um eine ID handelt. In diesem Fall schlage ich vor, Funktionen zu erstellen, um vor dem Speichern der Daten jedem Array-Element ein Zeichen hinzuzufügen, und eine weitere Funktion, um das Zeichen vor der Verwendung der Daten zu entfernen. In diesem Fall wird der serialisiertei:2
Index nicht miti:D2
den "echten" Daten verwechselt . Der Meta-Abfrage-Parameter sollte dann werden'value' => sprintf(':"D%s";', $value),
und Sie behalten die korrekte Funktionalität dieser wundervollen Antwort!LIKE
ist eine großartige und schnelle Möglichkeit, Ihren Server herunterzufahren (ganz zu schweigen von False Positives).Wenn Sie Einträge in die WP-Datenbank serialisieren, verlieren Sie in der Tat die Möglichkeit, Ihre Daten auf effiziente Weise abzufragen.
Die allgemeine Einsparung und Steigerung der Leistung, die Sie durch die Serialisierung erzielen, wird sich kaum bemerkbar machen. Möglicherweise erhalten Sie eine etwas kleinere Datenbankgröße, aber die Kosten für SQL-Transaktionen werden hoch sein, wenn Sie diese Felder jemals abfragen und versuchen, sie auf sinnvolle Weise zu vergleichen.
Speichern Sie stattdessen die Serialisierung für Daten, die Sie nicht auf diese Weise abfragen möchten, sondern auf die Sie nur passiv über den direkten WP-API-Aufruf
get_post_meta()
zugreifen. Mit dieser Funktion können Sie einen serialisierten Eintrag entpacken, um auch auf seine Array-Eigenschaften zuzugreifen.In der Tat zugewiesen den Wert von wahr wie in;
$meta = get_post_meta( $post->ID, 'key', true );
Gibt die Daten als Array zurück, auf das Sie wie gewohnt zugreifen können.
Sie können sich auf andere Datenbank- / Site-Optimierungen wie Caching, CSS und JS-Minimierung konzentrieren und diese Dienste bei Bedarf als CDN verwenden. Um nur einige zu nennen ... WordPress Codex ist ein guter Ausgangspunkt, um mehr zu diesem Thema zu erfahren : HIER
quelle
Ich habe mich gerade mit serialisierten Feldern beschäftigt und könnte sie abfragen. Nicht mit der meta_query, sondern mit einer SQL-Abfrage.
Die Abfrage sucht zuerst nach Posts mit dem passenden post_type, sodass weniger wp_postmeta-Datensätze gefiltert werden müssen. Dann habe ich eine where-Anweisung hinzugefügt, um die Zeilen durch Filtern weiter zu reduzieren
meta_key
Die IDs landen gut in einem Array, das für get_posts benötigt wird.
PS. MySQL v5.6 oder höher wird für eine gute Leistung bei Unterabfragen benötigt
quelle
Dieses Beispiel hat mir sehr geholfen. Es ist speziell für das S2Members-Plugin (das Benutzer-Metadaten serialisiert). Sie können jedoch einen Teil eines serialisierten Arrays im meta_key abfragen.
Es funktioniert mit der MySQL REGEXP-Funktion.
Hier ist die Quelle
Hier ist der Code, mit dem alle in den USA lebenden Benutzer befragt werden. Ich änderte es leicht, um eines meiner benutzerdefinierten Registrierungsfelder abzufragen, und es funktionierte in kürzester Zeit.
quelle
Ich denke, es gibt zwei Lösungen, die versuchen können, das Problem zu lösen, dass Ergebnisse sowohl als Zeichenfolge als auch als Ganzzahlen gespeichert werden. Es ist jedoch wichtig zu erwähnen, dass es nicht möglich ist, die Integrität der als Ganzzahl gespeicherten Ergebnisse zu gewährleisten, da diese Werte als serialisierte Arrays gespeichert werden und der Index und die Werte genau nach demselben Muster gespeichert werden. Beispiel:
wird wie folgt als serialisiertes Array gespeichert
Beachten Sie die
i:0
als erste Position des Arrays undi:37
als ersten Wert. Das Muster ist das gleiche. Aber gehen wir zu den Lösungen1) REGEXP-Lösung
Diese Lösung funktioniert für mich unabhängig davon, ob der Metawert als Zeichenfolge oder Zahl / ID gespeichert wird. Allerdings nutzt es
REGEXP
, was nicht so schnell ist wie mitLIKE
2) WIE Lösung
Ich bin mir über den Leistungsunterschied nicht sicher, aber dies ist eine Lösung, die
LIKE
sowohl für Zahlen als auch für Zeichenfolgen verwendet und funktioniertquelle
REGEXP
ist in bestimmten Situationen nett, aber wenn Sie verwenden könnenLIKE
, denke ich, dass es die vorzuziehende Methode ist. Ein alter Link, aber meiner Meinung nach immer noch recht nützlich: thingsilearn.wordpress.com/2008/02/28/… :-)LIKE
ist schneller. Aber dies ist eine Lösung, die sowohl für Zeichenfolgen als auch für Zahlen funktioniertLIKE
sowohl für Zahlen als auch für Zeichenfolgen funktioniert. Ich bin mir nicht sicher über die Leistung, weil es die Ergebnisse mitOR
Nachdem ich eine Reihe von Tipps zum Ausführen einer
WP_Query
Filterung nach serialisierten Arrays gelesen habe , habe ich Folgendes getan: Erstellen eines Arrays mit durch Kommas getrennten Werten mithilfe von implode in Verbindung mit einer$wpdb
benutzerdefinierten SQL-AbfrageFIND_IN_SET
, bei der die Liste mit durch Kommas getrennten Werten nach dem angeforderten Wert durchsucht wird.(Dies ähnelt der Antwort von Tomas, ist jedoch für die SQL-Abfrage etwas weniger leistungsintensiv.)
1. In functions.php:
yourname_save_post()
Verwenden Sie in Ihrer functions.php-Datei (oder wo immer Sie die Meta-Box einrichten) die Funktionum ein Array mit kommagetrennten Werten zu erstellen.
Sie möchten auch Ihre Ausgabevariable in der
yourname_post_meta()
Admin-Meta-Box-Konstruktionsfunktion auf ändern2. In der PHP-Vorlagendatei:
Test: Wenn Sie a ausführen
get_post_meta( $id );
, sollten SiecheckboxArray
anstelle eines serialisierten Arrays ein Array mit durch Kommas getrennten Werten sehen.Jetzt erstellen wir unsere benutzerdefinierte SQL-Abfrage mit
$wpdb
.Beachten Sie, das
FIND_IN_SET
ist, wo die Magie passiert.Nun ... da ich
SELECT *
dies verwende, werden alle Post-Daten zurückgegeben und in der könnenforeach
Sie das, was Sie wollen, wiedergeben (tunprint_r($posts);
Sie dies, wenn Sie nicht wissen, was enthalten ist. Es wird keine "Schleife" für eingerichtet Sie (ich bevorzuge es auf diese Weise), aber es kann leicht geändert werden, um die Schleife einzurichten, wenn Sie dies vorziehen (werfen Sie einen Blicksetup_postdata($post);
in den Codex, Sie müssen wahrscheinlich ändernSELECT *
, um nur Beitrags-IDs und$wpdb->get_results
den richtigen$wpdb
Typ auszuwählen - - Weitere$wpdb
Informationen zu diesem Thema finden Sie im Kodex .)Welpe, es hat ein bisschen Mühe gekostet, aber da serialisierte oder durch Kommas getrennte Werte
wp_query
nicht unterstützt'compare' => 'IN'
werden, ist dieses Shim Ihre beste Option!Hoffe das hilft jemandem.
quelle
Wenn Sie den
like
Vergleichsoperator in Ihrer Meta-Abfrage verwenden, sollte es gut funktionieren, in einem serialisierten Array nachzuschauen.Ergebnisse in:
quelle
Wenn meine Metadaten vom Typ Array sind, verwende ich diese Methode für die Abfrage nach Meta:
quelle
Ich wurde neugierig auf die obigen Antworten, bei denen
meta_query
der Schlüssellatitude
statt gezielt wurde_coordinates
. Ich musste testen, ob es in Meta-Abfragen wirklich möglich war, einen bestimmten Schlüssel innerhalb eines serialisierten Arrays zu ermitteln. :)Das war offensichtlich nicht der Fall.
Beachten Sie also, dass der richtige Schlüssel zum Ziel
_coordinates
anstelle von lautetlatitude
.ANMERKUNGEN:
Dieser Ansatz ermöglicht es nur, exakte Übereinstimmungen zu erzielen. Dinge wie alle Breiten über 50 sind also nicht möglich.
Um Teilstring-Übereinstimmungen einzuschließen, könnte man verwenden
'value' => sprintf(':"%%%s%%";', $value),
. (nicht getestet)quelle
Ich habe die gleiche frage Benötigen Sie den Parameter 'type'? Schauen Sie sich diese verwandte Frage an: Benutzerdefinierte Feldabfrage - Meta-Wert ist Array
Vielleicht versuchen Sie:
quelle
Ich bin auf etwas Ähnliches gestoßen, als ich das Magic Fields-Plugin verwendet habe. Dies könnte den Trick machen
quelle
serialize()
ist in diesem Fall nicht erforderlich ...