uzyskiwanie wszystkich wartości dla niestandardowego klucza pola (cross-post)

44

Wiem, jak uzyskać niestandardową wartość pola dla określonego postu.

get_post_meta($post_id, $key, $single);

Potrzebuję wszystkich wartości związanych z określonym niestandardowym kluczem postu we wszystkich postach .

Czy ktoś wie, jak to zrobić skutecznie? Nie chciałbym przeglądać wszystkich identyfikatorów postów w bazie danych.

Przykład:

4 posty z różnymi wartościami dla niestandardowego pola o nazwie „Nastrój”. 2 posty mają wartość „szczęśliwy”, 1 post ma „zły”, a 1 post „smutny”

Chcę generować: we wszystkich postach mamy: dwóch szczęśliwych, jednego gniewnego i jednego smutnego (-ych) autora (ów).

Ale dla WIELU postów.

To, czego szukam to:

  • funkcja WP, aby to uzyskać. lub
  • niestandardowe zapytanie, aby uzyskać je tak skutecznie, jak to możliwe.
mikkelbreum
źródło
5
Wygląda na to, że używasz tego jako taksonomii. Dlaczego po prostu (automatycznie) dodać termin do tych postów podczas zapisywania? Ułatwiłoby to tworzenie zapytań.
kaiser
@kaiser Nie mogę ci wystarczająco podziękować za to, że jesteś geniuszem!
user2128576,

Odpowiedzi:

58

Jednym z możliwych podejść byłoby użycie jednej z metod pomocniczych w klasie WPDB do wykonania bardziej dopracowanego zapytania opartego na meta. Warunkiem korzystania z niektórych z tych funkcji jest jednak to, że zwykle nie odzyskujesz prostej tablicy danych i zwykle musisz robić niepotrzebne odwołania do właściwości obiektu, nawet jeśli wywołujesz tylko jedną kolumnę lub wiersz.

Oczywiście nie wszystkie funkcje są takie same, a celowa wzmianka trafia do metody WPDB , get_colktóra zwraca prostą płaską tablicę danych , o które pytamy. Podaję tę informację konkretnie, ponieważ poniższy przykład wywoła tę metodę .

WordPress - WPDB Wybieranie kolumny danych
$ wpdb-> get_col ()

Oto przykładowa funkcja, która wysyła zapytanie do bazy danych dla wszystkich postów wybranego typu postu, statusu postu i określonego meta klucza (lub pola niestandardowego dla mniej technicznie nastawionych).

function get_meta_values( $key = '', $type = 'post', $status = 'publish' ) {

    global $wpdb;

    if( empty( $key ) )
        return;

    $r = $wpdb->get_col( $wpdb->prepare( "
        SELECT pm.meta_value FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = %s 
        AND p.post_status = %s 
        AND p.post_type = %s
    ", $key, $status, $type ) );

    return $r;
}

Na przykład, jeśli chcesz dowiedzieć się, które posty mają meta klucz oceny , w przypadku filmów typu post i chcesz przechowywać te informacje w zmiennej, przykładem takiego połączenia może być ...

$movie_ratings = get_meta_values( 'rating', 'movies' );

Jeśli nie chcesz nic więcej robić niż wydrukować te dane na ekranie, funkcja implode PHP może szybko podzielić tę prostą tablicę na linie danych.

// Print the meta values seperate by a line break
echo implode( '<br />', get_meta_values( 'YOURKEY' ));

Możesz również użyć zwróconych danych, aby dowiedzieć się, ile wpisów ma te meta wartości, wykonując na przykład prostą pętlę nad zwróconymi danymi i budując tablicę zliczeń.

$movie_ratings = get_meta_values( 'rating', 'movies' );
if( !empty( $movie_ratings ) ) {
    $num_of_ratings = array();
    foreach( $movie_ratings as $meta_value )
        $num_of_ratings[$meta_value] = ( isset( $num_of_ratings[$meta_value] ) ) ? $num_of_ratings[$meta_value] + 1 : 1;
}

/*
Result:
Array(
    [5] => 10
    [9] => 2
)
// ie. there are 10 movie posts with a rating of 5 and 2 movie posts with a rating of 9.
*/

Ta logika może być zastosowana do różnych rodzajów danych i rozszerzona na wiele różnych sposobów. Mam więc nadzieję, że moje przykłady były pomocne i wystarczająco proste do naśladowania.

t31os
źródło
3
Również fajny fakt dla przyszłych widzów, jeśli chcesz wyciągnąć tylko unikalne meta wartości - piszesz DISTINCTzaraz po SELECTpowyższej funkcji. Może się przydać.
Howdy_McGee
Myślę, że jest to niezwykle przydatne
Pablo SG Pacheco
Jak to zrobić i zwrócić posortowane wartości ?, myślę, że używając ORDER przez, ale nie mogę dowiedzieć się, jak go używać
efirvida
14

Chciałbym tylko dodać jedną drobną rzecz do powyższego kodu t31os . Zmieniłem „SELECT” na „SELECT DISTINCT”, aby wyeliminować zduplikowane wpisy, kiedy sam korzystałem z tego kodu.

Lehooo
źródło
1
Mogę sobie wyobrazić przypadki, w których poprawne byłoby posiadanie wielu meta wartości o tej samej wartości, a zatem nie dodałem tego do mojego kodu. Jeśli chcesz mieć odrębne wartości, byłby to jednak dobry sposób. Dodatkowo możesz również dodać to jako argument dla funkcji (więc możesz jej użyć lub nie, odpowiednio).
t31os
10

Używanie globalnego $ wpdb nie jest dobre ani potrzebne:

// function to grab all possible meta values of the chosen meta key.
function get_meta_values( $meta_key,  $post_type = 'post' ) {

    $posts = get_posts(
        array(
            'post_type' => $post_type,
            'meta_key' => $meta_key,
            'posts_per_page' => -1,
        )
    );

    $meta_values = array();
    foreach( $posts as $post ) {
        $meta_values[] = get_post_meta( $post->ID, $meta_key, true );
    }

    return $meta_values;

}

$meta_values = get_meta_values( $meta_key, $post_type );
Leon Francis Shelhamer
źródło
W większości przypadków byłaby to moja preferowana metoda. Robi pięć zapytań, a nie tylko jedno, ale ponieważ korzysta ze standardowych procedur WordPress do ich generowania i przesyłania, uruchomi się każde buforowanie specyficzne dla platformy (takie jak buforowanie obiektów WP Engine lub jakieś losowe wtyczki). Dane również być przechowywane w wewnętrznej pamięci podręcznej WordPress na czas trwania żądania, więc w razie potrzeby nie będzie trzeba ponownie pobierać z bazy danych.
Andrew Dinmore,
Wszelkie filtry zostaną również zastosowane do danych, co może być niezwykle ważne na przykład w witrynie wielojęzycznej. Wreszcie, ponieważ wykorzystuje tylko standardowe podstawowe funkcje WordPress, jest znacznie mniej prawdopodobne, że zostanie zepsuty przez przyszłą aktualizację.
Andrew Dinmore,
4

najszybszym sposobem byłoby niestandardowe zapytanie SQL i nie jestem pewien, ale możesz spróbować

$wpdb->get_results("
  SELECT posts.* , COUNT(*) 'moodcount'
  FROM $wpdb->posts as posts
  JOIN $wpdb->postmeta as postmeta
  ON postmeta.post_id = posts.ID
  AND postmeta.meta_key = 'Mood'
  GROUP BY postmeta.meta_key
");

Jeśli coś, to początek.

Bainternet
źródło
1
dzięki, ale czy nie należy unikać niestandardowych zapytań „za wszelką cenę”? Wolałbym użyć warstwy abstrakcji WP (czy to się tak nazywa?) ... ale oczywiście, jeśli nie jest to możliwe ..
mikkelbreum
Niestandardowe zapytania, jeśli są napisane we właściwy sposób, mogą być lepsze i należy ich unikać tylko wtedy, gdy nie wiesz, co robisz.
Bainternet
1
Zgadzam się z mwb. Niestandardowe zapytania są bardzo przydatne i praktyczne, ale myślę, że są one również znacznie cięższe na DB .. szczególnie przy użyciu funkcji SRT ..
krembo99
3

Aby uzyskać wszystkie wartości meta kluczem meta

Sprawdź kodeks wp-> db wordpress

$values = $wpdb->get_col("SELECT meta_value
    FROM $wpdb->postmeta WHERE meta_key = 'yourmetakey'" );
Wiki
źródło
3
Problemem z tym podejściem jest brak specyficzności, otrzymasz wiele wyników z takiego zapytania, które mogą obejmować wersje robocze, elementy z kosza, posty, strony i wszelkie inne istniejące typy postów. Nigdy nie powinieneś pytać o to, czego nie potrzebujesz, z pewnością wymagana jest tutaj specyficzność.
t31os
Chociaż prawdą jest, że można uzyskać wartości z innych typów postów i statusów, są chwile, kiedy wszystko, czego potrzebujesz, to wartości i nie użyłeś tego meta_key nigdzie, tylko tam, gdzie jest to potrzebne. Jeśli wszystkie / większość wartości są unikalne, może to być najlepsze rozwiązanie.
Luke Gedeon
2

Nie ma powodu, dla którego nie można scalić t31os i kodu Bainternet, aby uzyskać przygotowaną instrukcję wielokrotnego użytku (styl wordpress), która zwraca liczbę i wartości w jednej wydajnej operacji.

To niestandardowe zapytanie, ale nadal korzysta z warstwy abstrakcji bazy danych wordpress - więc na przykład nie ma znaczenia, jakie naprawdę są nazwy tabel lub czy się zmieniają, i jest to przygotowane oświadczenie, dzięki czemu jesteśmy o wiele bezpieczniejsi od ataków SQL itp. .

W tym przypadku nie sprawdzam już typu wpisu i wykluczam puste ciągi:

    $r = $wpdb->get_results(  $wpdb->prepare( "
        SELECT pm.meta_value AS name, count(*) AS count  FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = '%s'
        AND pm.meta_value != '' 
        AND p.post_type = '%s'
        GROUP BY pm.meta_value
        ORDER BY pm.meta_value          
        ", $key, $type) 
        );
    return $r;

W tym konkretnym jest

Zwróci tablicę obiektów takich jak:

array  
 0 => 
 object(stdClass)[359]
  public 'name' => string 'Hamish' (length=6)
  public 'count' => string '3' (length=1)
 1 => 
 object(stdClass)[360]
  public 'name' => string 'Ida' (length=11)
  public 'count' => string '1' (length=1)
 2 => 
 object(stdClass)[361]
  public 'name' => string 'John' (length=12)
  public 'count' => string '1' (length=1)
benz001
źródło
0

Używaj następujących narzędzi Foreach

 $key = get_post_custom_values( 'key' );

Zakłada, że ​​nazwa niestandardowego klucza pola to

Dev
źródło
Zauważ, że domyślnie jest to bieżący post, gdy nie określono identyfikatora post_id.
birgire,