Ich habe die folgende wp_query:
$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 Ergebnisse, da es nur 10 news
Beiträge mit a gibt meta_key = custom_author_name
. Es gibt jedoch Hunderte von news
Posts, die keine post_meta-Zeile mit diesem bestimmten meta_key haben. Bitte beachten Sie, dass keine meta_query beteiligt ist. Es wird kein meta_value zugewiesen, da ich nur versuche, die Beiträge nach meta_key zu sortieren und nicht nach meta_value zu filtern.
Sollte orderby nicht alle Beiträge auswählen? und einfach bestellen?
Wenn ja, warum wird das Ergebnis gefiltert? Wenn der meta_key nicht gefunden wird, warum nicht einfach eine leere Zeichenfolge oder eine Übereinstimmung mit allen verwenden?
Wenn nicht, warum nicht?
Wenn ich für jeden Nachrichtenbeitrag einen meta_key eingebe (auch wenn es sich um eine leere Zeichenfolge handelt), erhalte ich das erwartete Ergebnis. Aber das scheint eine ganze Menge Tabellenzeilen zu sein, die nicht vorhanden sein müssen.
quelle
'orderby' => 'meta_value'
, hat sie die Reihenfolge geändert, aber es hatte nichts mit dem tatsächlichen Metafeld zu tun.Ich habe versucht, die Antwort von @Manny Fleurmond anzuwenden, und wie bei @Jake konnte ich sie nicht zum Laufen bringen, selbst nachdem ich den Tippfehler korrigiert hatte, der
'orderby' => 'meta_key'
sein sollte'orderby' => 'meta_value'
. (Und der Vollständigkeit halber sollte es'posts_per_page'
nicht sein,'post_per_page'
aber das hat keinen Einfluss auf das betrachtete Problem.)Wenn Sie sich die SQL-Abfrage ansehen, die tatsächlich durch die Antwort von @Manny Fleurmond generiert wurde (nachdem Sie die Tippfehler korrigiert haben), erhalten Sie Folgendes:
Dies zeigt, wie WP die Abfragevariablen analysiert: Es erstellt eine Tabelle für jede meta_query-Klausel und findet dann heraus, wie sie verbunden werden sollen und nach was sortiert werden soll. Die Bestellung würde gut funktionieren, wenn Sie nur eine einzige Klausel mit verwenden würden
'compare' => 'EXISTS'
, aber wenn Sie die zweite'compare' => 'NOT EXISTS'
Klausel mit OR verbinden (wie wir müssen), wird die Bestellung durcheinander gebracht. Das Ergebnis ist, dass LEFT JOIN verwendet wird, um sowohl die erste Klausel / Tabelle als auch die zweite Klausel / Tabelle zu verbinden. Die Art und Weise, wie WP alles zusammenfügt, bedeutet, dass die mit erstellte Tabelle'compare' => 'EXISTS'
tatsächlich mit meta_values aus JEDEM benutzerdefinierten Feld gefüllt wird, nicht nur mit'custom_author_name'
Feld, an dem wir interessiert sind. Daher denke ich, dass die Bestellung nach dieser Klausel / Tabelle nur dann die gewünschten Ergebnisse liefert, wenn der bestimmte post_type von 'news' nur ein einziges benutzerdefiniertes Feld enthält.Die Lösung, die für meine Situation funktionierte, bestand darin, nach der anderen Klausel / Tabelle zu bestellen - der NOT EXISTS-Klausel. Ich weiß, dass dies scheinbar kontraintuitiv ist, aber aufgrund der Art und Weise, wie WP die Abfragevariablen analysiert, wird diese Tabelle
meta_value
nur mit dem benutzerdefinierten Feld gefüllt, nach dem wir suchen.(Der einzige Weg, dies herauszufinden, bestand darin, das Äquivalent dieser Abfrage für meinen Fall auszuführen:
Ich habe lediglich die angezeigten Spalten geändert und die GROUP BY-Klausel entfernt. Dies zeigte mir dann, was los war - dass die Spalte postmeta.meta_value Werte aus allen meta_keys abrief, während die Spalte mt1.meta_value nur meta_values aus dem benutzerdefinierten Nachrichtenfeld abrief.)
Die Lösung
Wie @Manny Fleurmond sagt, ist es die erste Klausel, die für die Bestellung verwendet wird. Die Antwort besteht also darin, die Klauseln zu vertauschen und Folgendes zu geben:
Alternativ können Sie die Klauseln zu assoziativen Arrays machen und nach dem entsprechenden Schlüssel sortieren, wie folgt:
quelle
custom_author_name
gesetzt und dann nicht gesetzt ist, dies daraufmeta_key
reagiertEXISTS
und der Effekt ist, dass diese neben Posts mit einem sprudelncustom_author_name
. In meinem Fall habe ich ein Kontrollkästchen, das ich"value" => "1"
anstelle von verwendeEXISTS
, aber Zeichenfolgen benötigen einen anderen Ansatz.So funktioniert es eigentlich.
Wenn Sie dies tun möchten, ohne Tabellenzeilen hinzuzufügen, müssen Sie zwei Abfragen durchführen. Einer mit dem meta_key, der die begrenzten Ergebnisse hat, und der andere, der die gesamte Liste erhält; Verwenden Sie dann PHP, um die beiden Abfrageergebnisse zu vergleichen (möglicherweise entfernen Sie die meta_key-Ergebnisse aus der anderen Abfrage, um Duplikate zu entfernen, oder was auch immer in Ihrer Einstellung sinnvoll ist).
quelle
Leider
WP_Query
funktioniert das nicht so . Sobald Sie diese "Meta" -Komponente hinzufügen, haben Sie eine Art Filter erstellt. Dump$query->request
und du wirst sehen, was ich meine.Zweitens wird
WP_Query
die Bestellung nach einem Meta- Schlüssel überhaupt nicht unterstützt . Sie können durch einen Meta bestellen Wert für einen bestimmten Schlüssel , aber nicht durch den Schlüssel selbst. Speichern Sie die Abfrage erneut, um zu sehen, was ich meine. Sie werden feststellen, dass die "Bestell" -Komponenten ausfallen, wenn Sie es versuchen.Der sauberste Weg, dies zum Laufen zu bringen, sind meiner Meinung nach ein paar kurze Filter:
quelle