mendapatkan semua nilai untuk kunci bidang khusus (lintas pos)

44

Saya tahu cara mendapatkan nilai bidang khusus untuk pos tertentu.

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

Yang saya butuhkan adalah mendapatkan semua nilai yang terkait dengan kunci posting khusus, di semua posting .

Adakah yang tahu cara yang efisien untuk melakukan ini? Saya tidak ingin mengulang semua postingan di DB.

Contoh:

4 posting semua dengan nilai yang berbeda untuk bidang khusus yang disebut 'Mood'. 2 posting memiliki nilai 'bahagia', 1 posting memiliki 'marah' dan 1 posting memiliki 'sedih'

Saya ingin menampilkan: di semua posting yang kami miliki: dua bahagia, satu marah dan satu penulis sedih.

Tetapi untuk BANYAK posting.

Yang saya cari adalah:

  • fungsi WP untuk mendapatkan ini. atau
  • permintaan khusus untuk mendapatkan ini seefisien mungkin.
mikkelbreum
sumber
5
Sepertinya Anda menggunakan ini sebagai taksonomi. Mengapa tidak secara sederhana (otomatis) menambahkan istilah ke posting ini saat menyimpan? Akan membuat permintaan lebih mudah.
kaiser
@kaiser Saya tidak bisa cukup berterima kasih karena telah menjadi jenius!
user2128576

Jawaban:

58

Salah satu pendekatan yang mungkin adalah menggunakan salah satu metode pembantu di kelas WPDB untuk melakukan kueri berbasis meta yang lebih disempurnakan. Peringatan untuk menggunakan beberapa fungsi ini, adalah bahwa Anda biasanya tidak mendapatkan kembali array data sederhana dan biasanya harus membuat referensi yang tidak perlu ke properti objek, bahkan jika Anda hanya memanggil satu kolom atau baris.

Tentu saja, tidak semua fungsi adalah satu dan sama, dan penyebutan yang disengaja keluar ke metode WPDB , get_colyang mengembalikan array datar sederhana dari data yang diminta, saya membuat penyebutan ini secara khusus karena contoh berikut akan memanggil metode ini .

WordPress - WPDB Memilih kolom data
$ wpdb-> get_col ()

Berikut adalah contoh fungsi yang menanyakan database untuk semua posting dari jenis posting yang dipilih, status posting dan dengan kunci meta tertentu (atau bidang khusus untuk yang kurang berpikiran teknis).

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;
}

Jadi misalnya, jika Anda ingin mengetahui postingan mana yang memiliki meta key rating , untuk film tipe postingan dan Anda ingin menyimpan informasi itu di dalam suatu variabel, contoh dari panggilan semacam itu adalah ..

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

Jika Anda ingin melakukan tidak lebih dari mencetak data itu ke layar, fungsi implode PHP dapat dengan cepat membagi array sederhana itu menjadi garis-garis data.

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

Anda juga dapat menggunakan data yang dikembalikan untuk mengetahui berapa banyak pos memiliki nilai meta ini dengan melakukan loop sederhana di atas data yang dikembalikan dan membangun array jumlah, misalnya.

$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.
*/

Logika ini dapat diterapkan untuk berbagai jenis data, dan diperluas untuk bekerja dengan berbagai cara. Jadi saya berharap contoh saya cukup membantu dan sederhana untuk diikuti.

t31os
sumber
3
Juga fakta yang menyenangkan bagi pemirsa di masa depan, jika Anda hanya ingin menarik nilai meta unik - Anda ketikkan DISTINCTtepat SELECTpada fungsi di atas. Bisa bermanfaat.
Howdy_McGee
Saya pikir ini sangat berguna
Pablo SG Pacheco
Bagaimana melakukan ini, dan mengembalikan nilai-nilai yang disortir ?, Saya pikir menggunakan ORDER oleh tetapi saya tidak tahu cara menggunakannya
efirvida
14

Saya hanya ingin menambahkan satu hal kecil ke kode t31os di atas. Saya mengubah "SELECT" menjadi "SELECT DISTINCT" untuk menghilangkan entri duplikat ketika saya menggunakan kode ini sendiri.

Lehooo
sumber
1
Saya bisa membayangkan kasus-kasus di mana itu valid untuk memiliki beberapa nilai meta dengan nilai yang sama, dan dengan demikian tidak membuat tambahan untuk kode saya. Jika Anda menginginkan nilai yang berbeda, ini akan menjadi cara untuk pergi. Selain itu Anda juga bisa menambahkan itu sebagai argumen untuk fungsi (sehingga Anda dapat menggunakannya atau tidak, sesuai kebutuhan).
t31os
10

Tidak baik atau diperlukan untuk menggunakan $ global wpdb:

// 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
sumber
Ini akan menjadi metode pilihan saya untuk melakukannya, dalam banyak kasus. Itu membuat lima pertanyaan, bukan hanya satu, tetapi, karena menggunakan prosedur WordPress standar untuk menghasilkan dan mengirimkannya, caching platform-spesifik (seperti Caching Objek WP Engine atau beberapa plugin acak) akan muncul. Data juga akan disimpan dalam cache internal WordPress selama permintaan, jadi tidak perlu diambil dari database lagi, jika diperlukan.
Andrew Dinmore
Filter apa pun juga akan diterapkan pada data, yang bisa sangat penting pada, misalnya, situs multi-bahasa. Terakhir, karena hanya menggunakan fungsi inti WordPress standar, kecil kemungkinannya akan rusak oleh pembaruan di masa mendatang.
Andrew Dinmore
4

cara tercepat adalah kueri sql khusus dan saya tidak yakin tetapi Anda dapat mencoba

$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
");

Jika ada maka ini adalah awal.

Bainternet
sumber
1
terima kasih, tetapi bukankah pertanyaan khusus harus dihindari 'sebisa mungkin'? Saya lebih suka menggunakan lapisan abstraksi WP (apakah itu sebutannya?) ... tapi tentu saja jika ini tidak mungkin ..
mikkelbreum
Kueri khusus, jika ditulis dengan cara yang benar, bisa lebih baik dan Anda hanya harus menghindarinya jika Anda tidak tahu apa yang Anda lakukan.
Bainternet
1
Saya Setuju dengan mwb .custom queries sangat berguna dan praktis, tetapi saya pikir mereka juga jauh lebih berat pada DB .. terutama menggunakan fungsi SRT ..
krembo99
3

Untuk mendapatkan semua nilai meta dengan kunci meta

Periksa wp-> codex wordpress db

$values = $wpdb->get_col("SELECT meta_value
    FROM $wpdb->postmeta WHERE meta_key = 'yourmetakey'" );
Wiki
sumber
3
Masalah dengan pendekatan ini adalah kurangnya kekhususan, Anda akan mendapatkan banyak hasil dari permintaan seperti itu, yang dapat mencakup konsep, item yang dibuang, posting, halaman, dan jenis posting lainnya yang ada. Anda seharusnya tidak pernah menanyakan apa yang tidak Anda butuhkan, spesifisitas pasti diperlukan di sini.
t31os
Meskipun benar bahwa Anda bisa mendapatkan nilai dari jenis dan status pos lain, ada kalanya yang Anda butuhkan hanyalah nilai dan Anda belum pernah menggunakan meta_key itu di mana pun kecuali di mana Anda membutuhkannya. Jika semua / sebagian besar nilai unik, ini mungkin solusi terbaik.
Luke Gedeon
2

Tidak ada alasan mengapa Anda tidak dapat menggabungkan t31os dan kode Bainternet untuk memiliki pernyataan siap pakai yang dapat digunakan kembali (gaya wordpress) yang mengembalikan hitungan dan nilai-nilai dalam satu operasi yang efisien.

Ini permintaan khusus tetapi masih menggunakan lapisan abstraksi database wordpress - jadi misalnya tidak masalah apa nama tabel sebenarnya, atau jika mereka berubah, dan itu adalah pernyataan yang disiapkan sehingga kita jauh lebih aman dari serangan SQL dll .

Dalam hal ini saya tidak lagi memeriksa jenis posting dan saya mengecualikan string kosong:

    $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;

Khususnya ini

Ini akan mengembalikan array objek seperti:

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
sumber
0

Gunakan yang berikut dengan foreach

 $key = get_post_custom_values( 'key' );

Diasumsikan nama kunci bidang khusus Anda adalah

Dev
sumber
Perhatikan bahwa ini default ke posting saat ini, ketika tidak ada post_id ditentukan.
birgire