Bisakah wp_query mengembalikan meta pos dalam satu permintaan?

22

Saya ingin membuat wp_query yang akan mengembalikan posting meta di dalam postsarray.

$args = array (
    'post_type' => 'page',
    'meta_key' => 'someMetaKeyName',
);

// The Query
$query = new WP_Query( $args );

Ini mengembalikan sesuatu seperti:

masukkan deskripsi gambar di sini

Seperti yang Anda lihat posting tidak memiliki data meta, apakah mungkin untuk memasukkan data meta dalam array yang dikembalikan juga?

PS Saya tidak ingin wp_queries tambahan karena alasan kinerja.

YemSalat
sumber
2
WP_Query standar tidak mengembalikan data meta posting. Satu-satunya pilihan yang Anda miliki adalah: 1) berjalan get_post_metapada kunci individual, 2) menjalankan get_post_customuntuk mendapatkan semua bidang kustom posting dalam satu kesempatan, atau 3) membuat kueri Anda sendiri menggunakan $ wpdb class ( get_results()) untuk membangun objek kembali Anda sendiri . ($ wpdb dokumentasi kelas: codex.wordpress.org/Class_Reference/wpdb )
BODA82

Jawaban:

20

Secara default, WP_Querymengembalikan WP_Postobjek standar untuk posting yang ditanyai. Saya percaya dengan beberapa penulisan ulang yang cerdas dan penggunaan filter yang diberikan pada WP_QueryAnda dapat menambahkan objek ke WP_Postarray objek yang dikembalikan .

Apakah ini akan menjadi pemain? Menurut pendapat saya, itu akan lebih merusak kinerja karena Anda harus menggabungkan hasil dalam kueri Anda karena bidang khusus tidak disimpan dalam wp_poststabel, tetapi dalam wp_postmetatabel

Mengambil posting meta sangat cepat dan tidak memerlukan contoh tambahan WP_Query. Anda cukup memanggil bidang khusus dengan get_post_meta(). WordPress sangat bijaksana ketika bidang kustom diperkenalkan. Mereka menambahkan cache ke cache mereka, jadi apakah Anda meminta 1 atau 100 bidang khusus, Anda memukul database sekali, super cepat. Untuk tes dan penjelasan lengkap, lihat posting ini yang baru-baru ini saya lakukan pada subjek ini.

Menurut pendapat saya, panggilan basis data tambahan dan waktu aktual yang dihabiskan sepadan dan lebih cepat daripada menulis ulang WP_Querysedemikian rupa untuk memasukkan bidang khusus dalam objek pos standar yang dikembalikan oleh$posts

Pieter Goosen
sumber
OK, terima kasih, saya akan memilih yang ini sebagai diterima, tetapi jujur ​​saja ini merepotkan get_post_meta()untuk setiap posting .. Saya lebih suka ada cara untuk menyimpan data tambahan baik secara langsung di wp_poststabel, atau dalam tabel terkait yang tidak sebanyak mindf * ck seperti wp_postsmetaini.
YemSalat
Sejujurnya, apakah memanggil get_post_meta()atau sebagai objek posting, Anda harus memanggilnya di setiap posting. Itu sama dengan tag templat seperti the_content(), Anda harus menyebutnya di setiap posting.
Pieter Goosen
2
Ini berarti bahwa jika Anda harus menampilkan 120 posting, Anda akan memiliki 120 pertanyaan tambahan di halaman Anda?
chifliiiii
Semua postdata disimpan dalam cache, jadi Anda tidak akan memiliki pertanyaan tambahan ketika cal; ling post meta
Pieter Goosen
Kamu benar. Saya merujuk ke post_thumbnails tetapi saya baru-baru ini menemukan update_post_thumbnail_cache ($ the_query). Terima kasih atas klarifikasi
chifliiiii
4

Pertanyaan ini sudah lebih dari 1 tahun, tetapi saya memiliki masalah yang sama, dan di sini adalah fungsi yang akan menambahkan setiap meta_value dan meta_key ke objek $ wp_query,

alih-alih meminta setiap meta pos dalam loop sementara, fungsi ini akan melakukan Satu contoh kueri tambahan:

"SELECT meta_key, meta_value, post_id DARI $ wpdb-> postmeta WHERE post_id IN (1,2,3,4,5 ...)"

di mana (1,2,3,4,5 ...) saat ini meminta ID posting dari $ wp_query

if(!function_exists('add_query_meta')) {
  function add_query_meta($wp_query = "") {

      //return In case if wp_query is empty or postmeta already exist
      if( (empty($wp_query)) || (!empty($wp_query) && !empty($wp_query->posts) && isset($wp_query->posts[0]->postmeta)) ) { return $wp_query; }

      $sql = $postmeta = '';
      $post_ids = array();
      $post_ids = wp_list_pluck( $wp_query->posts, 'ID' );
      if(!empty($post_ids)) {
        global $wpdb;
        $post_ids = implode(',', $post_ids);
        $sql = "SELECT meta_key, meta_value, post_id FROM $wpdb->postmeta WHERE post_id IN ($post_ids)";
        $postmeta = $wpdb->get_results($sql, OBJECT);
        if(!empty($postmeta)) {
          foreach($wp_query->posts as $pKey => $pVal) {
            $wp_query->posts[$pKey]->postmeta = new StdClass();
            foreach($postmeta as $mKey => $mVal) {
              if($postmeta[$mKey]->post_id == $wp_query->posts[$pKey]->ID) {
                $newmeta[$mKey] = new stdClass();
                $newmeta[$mKey]->meta_key = $postmeta[$mKey]->meta_key;
                $newmeta[$mKey]->meta_value = maybe_unserialize($postmeta[$mKey]->meta_value);
                $wp_query->posts[$pKey]->postmeta = (object) array_merge((array) $wp_query->posts[$pKey]->postmeta, (array) $newmeta);
                unset($newmeta);
              }
            }
          }
        }
        unset($post_ids); unset($sql); unset($postmeta);
      }
      return $wp_query;
  }
}

Additioanal "postmeta" akan ditulis untuk setiap $ wp_query-> postingan [$ i]

$wp_query->posts[0]->postmeta

Contoh dengan 'someMetaKeyName' jangan lupa cantumkan

add_query_meta() ke functin.php tema Anda

$args = array (
    'post_type' => 'page',
    'meta_key' => 'someMetaKeyName',
);

// The Query
$query = new WP_Query( $args );
if($wp_query->have_posts()) {
  $wp_query = add_query_meta($wp_query);
    $i = 0;
    while($wp_query->have_posts()) {
      $wp_query->the_post();
      $post_id = get_the_id();

      //Get $someMetaKeyName in current post
      foreach($wp_query->posts[$i]->postmeta as $k => $v) {
        switch($v->meta_key) {
          case('someMetaKeyName') : {
            $someMetaKeyName = $v->meta_value;
            break;
          }
        }
      }

      //Your Code here
      //Example 
      echo isset($someMetaKeyName) ? '<h3>'.$someMetaKeyName.'</h3>' : '';


      $i++;
    }
}
Jonny
sumber
Saya suka solusi ini.
Armstrongest
3

Saya memiliki masalah yang sama baru-baru ini, saya perlu mendapatkan 7 lembar metadata dari jenis pos kustom, tetapi juga perlu mendapatkan pos berdasarkan sepotong metadata.

Jadi saya membuat pernyataan SQL berikut, saya sering menggunakannya. Semoga ini bisa membantu orang lain. Saya akan mencoba menjelaskannya semampu saya.

        global $wpdb;
        $pt = 'clients';
        $mk = 'trainerid';
        $mv = $pid;
        $mk1 = 'email';
        $mk2 = 'phone';
        $mk3 = 'gender';
        $mk4 = 'dob';
        $mk5 = 'photo';
        $mk6 = 'registrationts';
        $mk7 = 'activationts';
        $ord = 'p.post_name ASC';

        $sql = "
        SELECT p.ID, p.post_title AS fullname, pm1.meta_value AS email, pm2.meta_value AS phone, pm3.meta_value AS gender, pm4.meta_value AS dob, pm5.meta_value AS photo, pm6.meta_value AS regts, pm7.meta_value AS actemailts
        FROM {$wpdb->posts} p
            LEFT JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID
            AND pm.meta_key = '{$mk}'
            LEFT JOIN {$wpdb->postmeta} pm1 ON pm1.post_id = p.ID
            AND pm1.meta_key = '{$mk1}'
            LEFT JOIN {$wpdb->postmeta} pm2 ON pm2.post_id = p.ID
            AND pm2.meta_key = '{$mk2}'
            LEFT JOIN {$wpdb->postmeta} pm3 ON pm3.post_id = p.ID
            AND pm3.meta_key = '{$mk3}'
            LEFT JOIN {$wpdb->postmeta} pm4 ON pm4.post_id = p.ID
            AND pm4.meta_key = '{$mk4}'
            LEFT JOIN {$wpdb->postmeta} pm5 ON pm5.post_id = p.ID
            AND pm5.meta_key = '{$mk5}'
            LEFT JOIN {$wpdb->postmeta} pm6 ON pm6.post_id = p.ID
            AND pm6.meta_key = '{$mk6}'
            LEFT JOIN {$wpdb->postmeta} pm7 ON pm7.post_id = p.ID
            AND pm7.meta_key = '{$mk7}'
            WHERE pm.meta_value = '{$mv}'
            AND p.post_type = '{$pt}'
            AND p.post_status NOT IN ('draft','auto-draft')
            ORDER BY {$ord}
        ";

        $clients = $wpdb->get_results( $wpdb->prepare( $sql ), OBJECT );

Pertama saya mendapatkan fungsi database wordpress dengan global $ wpdb. Lalu saya mengatur posttype dengan $ pt. Untuk mendapatkan postingan yang benar yang cocok dengan nilai spesifik di post_meta, saya menetapkan $ mk (meta_key)

Lalu saya atur $ mv (meta_value) var. (dalam hal ini nilai meta cocok dengan postid)

$ mk1- $ mk7 adalah meta_keys yang saya inginkan dari setiap posting. (Saya akan mengambil nilai dalam pernyataan pilih)

Saya juga membuat 'order by' var, dengan menetapkan $ ord

Pernyataan pilih berjalan sebagai berikut: Saya memilih ID posting dan post_title dari POST atau 'hal.'

Kemudian saya memilih semua metadata yang saya perlu memilihnya dengan pm1. -> pm.7 dan meraih meta_value dan menamainya kembali (AS) sehingga lebih mudah dibaca ketika mengambil data dari objek saya.

Saya membuat BERGABUNG KIRI untuk meta data yang saya butuhkan untuk mencocokkan dengan posting. (sore)

Saya membuat 7 gabungan kiri untuk masing-masing meta data yang perlu saya ambil. (pm1-pm7)

Pernyataan WHERE didasarkan pada LEFT JOIN (pm) pertama sehingga saya akan tahu bahwa saya hanya perlu posting di mana metadata cocok.

Saya juga menambahkan 'DAN' untuk jenis posting, dan untuk post_status yang bukan konsep. (jadi hanya posting yang dipublikasikan)

Akhirnya saya menambahkan klausa 'pesanan oleh'.

Ini berfungsi cepat dan dengan indeks bawaan di Wordpress, sehingga tampaknya efisien.

Tidak tahu apakah ada sesuatu yang lebih baik dari ini, tetapi jika ya, saya ingin menggunakannya.

Semoga ini membantu.

Marcus

Marcus
sumber
Terima kasih, posting ini sangat membantu. Saya membuat tampilan dengan semua bidang meta yang saya butuhkan dan sekarang sangat cepat dan mudah untuk mendapatkan data yang saya inginkan
Liko
0

Hei Silakan coba yang ini saya pikir itu berfungsi dengan baik.

$args = array(
            'post_type' => 'page',
            'meta_key' => 'someMetaKeyName',
            'meta_query' => array(
                array(
                        'key' => 'someMetaKeyName',
                        'type' => 'CHAR',
                   ),
                ),
        );

    $query = new WP_Query( $args );
Amit Mishra
sumber
Apa alasan Anda menggunakannya meta_keydan meta_query[]['key']juga?
kaiser
1
Tidak, ini tidak berfungsi dan mengembalikan larik posting tanpa meta yang terkait dengannya.
YemSalat
3
meta_keydan / atau meta_querytidak mengubah jenis hasil yang dikembalikan, hanya permintaan itu sendiri.
BODA82