Wp_query tek bir istekle meta gönderebilir mi?


22

postsDizi içinde meta gönderen bir wp_query oluşturmak istiyorum .

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

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

Bu şöyle bir şey döndürür:

görüntü tanımını buraya girin

Gördüğünüz gibi gönderilerin herhangi bir meta verisi yok, meta verinin döndürülen diziye eklenmesi de mümkün mü?

PS Performans nedeniyle ek wp_queries istemiyorum.


2
Standart WP_Query bir yazı meta verisi döndürmüyor. Sahip olduğunuz tek seçenek şunlardır: 1) get_post_metatek tek tuşlar üzerinde koşmak , 2) get_post_customtüm gönderilerin özel alanları tek seferde almak için koşmak veya 3) $ wpdb sınıfını ( get_results()) kullanarak kendi dönüş nesnenizi oluşturmak için kendi sorgunuzu oluşturmak . ($ wpdb sınıfı dokümantasyon: codex.wordpress.org/Class_Reference/wpdb )
BODA82

Yanıtlar:


20

Varsayılan olarak, sorgulanan gönderiler için WP_Querystandart WP_Postnesneleri döndürür . Bazı akıllıca yeniden yazma ve WP_Querysize verilen filtrelerin kullanımı ile döndürülen WP_Postnesneler dizisine nesne ekleyebileceğime inanıyorum .

Bu performans gösterecek mi? Bence, bu özel alanlar içinde kaydedilmez gibi Sorgunuzda sonuçlarını katılmak gerekir gibi daha performansını olumsuz olacaktır wp_poststabloda ancak, wp_postmetamasanın

Post meta alma işlemi gerçekten hızlıdır ve fazladan bir örneği gerektirmez WP_Query. Özel alanı yalnızca ile arayabilirsiniz get_post_meta(). Özel alanlar tanıtıldığında WordPress çok düşünceliydi. Onları önbelleğe almak için bir önbellek eklediler, yani 1 veya 100 özel alan sorgusu yapıyorsanız, veritabanına bir kez vuruyorsunuz, süper hızlı. Tam bir test ve açıklama için, son zamanlarda bu konuda yaptığım bu yazıya bakın .

Benim görüşüme göre, ekstra veritabanı çağrısı ve harcanan gerçek zaman buna değer ve WP_Querygeri gönderilen standart post nesnesine özel alanları içerecek şekilde yeniden yazmaktan daha hızlıdır$posts


Tamam, teşekkürler, kabul olarak bu birini seçeriz, ama onun sadece çok güçlük çağırarak dürüst olmak gerekirse get_post_meta()her yazı için .. Daha doğrusu orada ya doğrudan ek veri depolamak için bir yol oldu ediyorum wp_postsmasaya ya da içinde Bir mindf * ck kadar değil ilgili tablo wp_postsmeta.
YemSalat

Dürüst olmak gerekirse, get_post_meta()onu bir post nesnesi olarak çağırmak veya çağırmak için her yazıda onu aramanız gerekir. the_content()Her yazı için onu aramak zorunda gibi şablon etiketleri ile aynıdır .
Pieter Goosen

2
Bunun anlamı, eğer 120 yazı göstermek zorundaysanız, sayfanızda fazladan 120 sorgu alacağınız?
chifliiiii 14:15

Tüm posta verileri bir önbellekte saklanır, bu nedenle cal olduğunda ekstra sorgularınız olmaz; ling post meta
Pieter Goosen

Haklısın. Ben post_thumbnails atıfta bulundu ama son zamanlarda update_post_thumbnail_cache ($ the_query) bulundu. Açıklama için yine de teşekkürler
chifliiiii 14:15

4

Bu soru 1 yıldan daha eski, ancak aynı sorunum var ve burada her meta_value ve meta_key'i $ wp_query nesnesine ekleyen bir işlev var,

Döngü sırasında her yazı meta sorgulamak yerine, bu işlev bir ekstra sorgu örneği yapacaktır:

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

burada (1,2,3,4,5 ...) kıvırcık bir şekilde sorgulandı

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", her $ wp_query-> yazına [$ i] yazılacak

$wp_query->posts[0]->postmeta

'SomeMetaKeyName' ile örnek koymak için unutma

add_query_meta() temanıza functin.php

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

Bu çözümü seviyorum.
Armstrongest

3

Son zamanlarda benzer bir sorun yaşadım, özel bir yazı türünden 7 parça meta veri almam gerekiyordu, ancak bir meta veri parçasını temel alarak yazıyı da almam gerekiyordu.

Bu yüzden aşağıdaki SQL deyimini oluşturdum, sık kullanıyorum. Umarım başka birine yardım eder. Bunu elimden geldiğince açıklamaya çalışacağım.

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

İlk önce wordpress veritabanı fonksiyonlarını global $ wpdb ile alıyorum. Sonra posttipi $ pt ile ayarlıyorum. Post_meta'da belirli bir değerle eşleşen doğru gönderiyi almak için, $ mk (meta_key) değerini ayarladım.

Sonra $ mv (meta_value) var değerini ayarladım. (bu durumda meta değeri bir postid ile eşleşir)

$ mk1- $ mk7, her yazıdan istediğim meta_keylerdir. (Select deyimindeki değerleri alacağım)

Ayrıca $ ord ayarlayarak 'order' a var var

Select deyimi şu şekilde gider: POST veya 'p' arasından yazı kimliğini ve yazı_yazısını seçiyorum.

Ardından, pm1 ile seçmem gereken tüm meta verileri seçiyorum. -> pm.7 ve meta_value değerini alıp isimlendirmek (AS), böylece nesnemden veri alınırken daha okunabilir.

Gönderi ile eşleştirmem gereken meta veriler için bir LEFT JOIN yaratıyorum. (Pm)

Almam gereken her meta veri için 7 tane solaryum oluşturdum. (PM1-PM7)

WHERE ifadesi, ilk LEFT JOIN (pm) 'e dayanmaktadır, böylece yalnızca meta verinin eşleştiği noktalara ihtiyacım olduğunu bilecektir.

Ayrıca yazı tipi ve taslak olmayan post_status için 'VE' eklerim. (bu yüzden yalnızca yayınlanmış yayınlar)

Sonunda 'by by' cümlesini ekliyorum.

Bu hızlı ve Wordpress'teki yerleşik indekslerle çalışır, bu yüzden verimli görünüyor.

Bundan daha iyi bir şey olup olmadığını bilmiyorum, ama öyleyse, onu kullanmayı çok isterim.

Bu yardımcı olur umarım.

Marcus


Teşekkürler, bu yazı çok yardımcı oldu. İhtiyacım olan tüm meta alanları içeren bir görünüm oluşturdum ve şimdi istediğim herhangi bir veriyi elde etmek için çok hızlı ve kolay
Liko

0

Hey Lütfen bunu dene, bence iyi sonuç veriyor.

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

    $query = new WP_Query( $args );

Neden kullandığın meta_keyve neden meta_query[]['key']?
kaiser

1
Hayır, bu işe yaramaz ve metalarla ilişkilendirilmiş olmayan yazı dizisini geri getirir.
YemSalat

3
meta_keyve / veya meta_querydöndürülen sonuçların türünü değiştirmeyin, yalnızca sorgunun kendisini değiştirin.
BODA82
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.