Mam następujące 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 wyników, ponieważ jest tylko 10 news
postów z meta_key = custom_author_name
. Ale istnieją setki news
postów, które nie mają wiersza post_meta z tym konkretnym meta_key. Zauważ, że nie ma w tym udziału meta_query. Nie przypisano żadnej wartości meta_wartości, ponieważ próbuję tylko posortować posty według meta_key, a nie filtrować według meta_value.
Czy nie należy zamawiać przez zaznaczenie wszystkich postów? i po prostu je zamówić?
Jeśli tak, dlaczego wynik jest filtrowany? Jeśli nie znaleziono klucza meta_key, dlaczego po prostu nie użyć pustego ciągu lub dopasować wszystko?
Jeśli nie, dlaczego nie?
Jeśli wprowadzę meta_key do każdego postu z wiadomościami (nawet jeśli jest to pusty ciąg), otrzymam oczekiwany wynik. Ale to wygląda na wiele rzędów tabel, które nie muszą tam być.
źródło
'orderby' => 'meta_value'
, zmieniło kolejność, ale nie miało nic wspólnego z rzeczywistym polem meta.Próbowałem stosowania odpowiedź @Manny Fleurmond i jak @Jake nie mogę zmusić go do pracy nawet po skorygowaniu literówkę, że
'orderby' => 'meta_key'
powinna być'orderby' => 'meta_value'
. (I dla kompletności powinno być'posts_per_page'
nie'post_per_page'
ale to nie wpływa na kwestię badana).Jeśli spojrzysz na zapytanie SQL faktycznie wygenerowane przez odpowiedź @Manny Fleurmond (poprawiając literówki), otrzymujesz:
To ilustruje sposób, w jaki WP analizuje zmienne zapytania: tworzy tabelę dla każdej klauzuli meta_query, a następnie zastanawia się, jak do nich dołączyć i jak zamówić. Kolejność działałaby dobrze, gdybyś używał tylko jednej klauzuli z
'compare' => 'EXISTS'
, ale połączenie drugiej'compare' => 'NOT EXISTS'
klauzuli z OR (jak musimy) zakłóca porządkowanie. W rezultacie LEFT JOIN jest używany do łączenia zarówno pierwszej klauzuli / tabeli, jak i drugiej klauzuli / tabeli - a sposób, w jaki WP'compare' => 'EXISTS'
składa wszystko razem, oznacza, że tabela utworzona za pomocą jest faktycznie wypełniana meta_wartościami z DOWOLNEGO niestandardowego pola, a nie tylko'custom_author_name'
pole, którym jesteśmy zainteresowani. Myślę więc, że uporządkowanie według tej klauzuli / tabeli da pożądane wyniki tylko wtedy, gdy określony typ postu „news” ma tylko jedno niestandardowe pole.Rozwiązaniem, które zadziałało w mojej sytuacji, było zamówienie według drugiej klauzuli / tabeli - NIE ISTNIEJĄCEJ. Wiem, pozornie intuicyjne, ale ze względu na sposób, w jaki WP analizuje zmienne zapytania, jest to tabela, w której
meta_value
zapełniane są tylko pola niestandardowe, których szukamy.(Jedynym sposobem, w jaki do tego doszedłem, było uruchomienie odpowiednika tego zapytania dla mojej sprawy:
Wszystko, co zrobiłem, to zmiana wyświetlanych kolumn i usunięcie klauzuli GROUP BY. To pokazało mi, co się dzieje - że kolumna postmeta.meta_value pobierała wartości ze wszystkich kluczy meta_keys, a kolumna mt1.meta_value pobierała tylko wartości meta_value z niestandardowego pola wiadomości.)
Rozwiązanie
Jak mówi @Manny Fleurmond, jest to pierwsza klauzula używana do zamówienia, więc odpowiedź polega na zamianie rund klauzul, co daje:
Alternatywnie możesz utworzyć klauzule tablic asocjacyjnych i uporządkować według odpowiedniego klucza, na przykład:
źródło
custom_author_name
zostanie ustawiony, a następnie rozbrojony, tometa_key
zareaguje,EXISTS
a efekt będzie taki, że będą one bąbelkowane obok postów, które mającustom_author_name
. W moim przypadku mam pole wyboru, więc używam"value" => "1"
zamiastEXISTS
, ale ciągi będą wymagały innego podejścia.Właśnie tak to działa.
Jeśli chcesz to zrobić bez dodawania wierszy tabeli, musisz wykonać dwa zapytania. Jeden z meta_key, który ma ograniczone wyniki, a drugi z całą listą; następnie użyj PHP, aby porównać dwa wyniki zapytania (ewentualnie usuń wyniki meta_key z drugiego zapytania, aby usunąć duplikaty lub cokolwiek innego, co ma sens w twoim ustawieniu).
źródło
Niestety nie tak to
WP_Query
działa. Jak tylko dodasz ten komponent „meta”, stworzyłeś swego rodzaju filtr. Zrzuć,$query->request
a zobaczysz, co mam na myśli.Po drugie, w
WP_Query
ogóle nie obsługuje zamawiania według meta- klucza . Możesz zamówić według wartości meta dla określonego klucza, ale nie według samego klucza. Ponownie zrzuć zapytanie, aby zobaczyć, co mam na myśli. Zauważysz, że składniki „zamówienia” wypadają, jeśli spróbujesz.Moim zdaniem najczystszym sposobem, aby to zadziałało, jest kilka krótkich filtrów:
źródło