wp_query ส่งคืนเมตาโพสต์ในคำขอเดียวได้หรือไม่


22

ฉันต้องการสร้าง wp_query ที่จะส่งคืนเมตาโพสต์ภายในpostsอาเรย์

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

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

ส่งคืนสิ่งที่ต้องการ:

ป้อนคำอธิบายรูปภาพที่นี่

ในขณะที่คุณเห็นโพสต์ไม่มีข้อมูลเมตาใด ๆ เป็นไปได้หรือไม่ที่จะรวมข้อมูลเมตาในอาเรย์ที่ส่งคืนด้วย

PS ฉันไม่ต้องการ wp_queries เพิ่มเติมเนื่องจากเหตุผลด้านประสิทธิภาพ


2
WP_Query มาตรฐานจะไม่ส่งคืนข้อมูลเมตาของโพสต์ ตัวเลือกเดียวที่คุณต้องมีคือ: 1) เรียกใช้get_post_metaบนแต่ละคีย์ 2) เรียกใช้get_post_customเพื่อรับฟิลด์โพสต์ที่กำหนดเองทั้งหมดในนัดเดียวหรือ 3) สร้างคิวรีของคุณเองโดยใช้คลาส $ wpdb ( get_results()) เพื่อสร้างออบเจ็กคืนของคุณเอง . (เอกสารคู่มือคลาส $ wpdb: codex.wordpress.org/Class_Reference/wpdb )
BODA82

คำตอบ:


20

โดยค่าเริ่มต้นWP_Queryส่งกลับWP_Postวัตถุมาตรฐานสำหรับโพสต์ที่ถูกสอบถาม ฉันเชื่อว่ามีการเขียนที่ฉลาดและการใช้ตัวกรองที่กำหนดในWP_Queryคุณสามารถเพิ่มวัตถุในWP_Postอาร์เรย์วัตถุที่ส่งคืน

สิ่งนี้จะเป็นนักแสดงหรือไม่? ในความคิดของฉันมันจะทำให้ประสิทธิภาพการทำงานลดลงเนื่องจากคุณจะต้องเข้าร่วมผลลัพธ์ในแบบสอบถามของคุณเนื่องจากเขตข้อมูลที่กำหนดเองไม่ได้บันทึกในwp_postsตาราง แต่ในwp_postmetaตาราง

WP_Queryการดึงข้อมูลโพสต์เมตาเป็นไปอย่างรวดเร็วและไม่จำเป็นต้องมีอินสแตนซ์พิเศษ คุณสามารถโทรหาฟิลด์ที่กำหนดเองget_post_meta()ได้ง่ายๆ WordPress นั้นช่างคิดมากเมื่อนำเสนอฟิลด์ที่กำหนดเอง พวกเขาเพิ่มแคชเพื่อแคชพวกเขาดังนั้นไม่ว่าคุณจะทำการสืบค้น 1 หรือ 100 ฟิลด์ที่กำหนดเองคุณกำลังกดฐานข้อมูลหนึ่งครั้งเร็วมาก สำหรับการทดสอบและคำอธิบายที่สมบูรณ์ดูโพสต์นี้ที่ฉันเพิ่งทำในเรื่องนี้

ในความคิดของฉันการเรียกฐานข้อมูลเพิ่มเติมและเวลาจริงที่ใช้ไปนั้นคุ้มค่าและเร็วกว่าการเขียนใหม่WP_Queryในลักษณะที่จะรวมเขตข้อมูลที่กำหนดเองในวัตถุโพสต์มาตรฐานที่ส่งคืนโดย$posts


ตกลงขอบคุณฉันจะเลือกอันนี้เป็นที่ยอมรับ แต่บอกตามตรงว่ามันยุ่งยากมากget_post_meta()สำหรับการโพสต์ทุกครั้ง .. ฉันอยากจะมีวิธีจัดเก็บข้อมูลเพิ่มเติมทั้งโดยตรงในwp_postsตารางหรือใน ตารางที่เกี่ยวข้องซึ่งไม่เท่าของ mindf A * CK เป็นwp_postsmetaมี
YemSalat

เพื่อความซื่อสัตย์ไม่ว่าจะเป็นการโทรget_post_meta()หรือโพสต์วัตถุคุณจะต้องโทรหามันในทุกโพสต์ มันเหมือนกันกับแท็กแม่แบบเช่นthe_content()คุณต้องโทรหามันในทุกโพสต์
Pieter Goosen

2
ซึ่งหมายความว่าหากคุณต้องแสดงโพสต์ 120 โพสต์คุณจะมีข้อความค้นหาเพิ่มเติม 120 รายการในหน้าของคุณ
chifliiiii

Postdata ทั้งหมดได้รับการบันทึกไว้ในแคชดังนั้นคุณจะไม่มีข้อสงสัยเพิ่มเติมเมื่อ cal; ling post meta
Pieter Goosen

คุณพูดถูก ฉันอ้างถึง post_thumbnails แต่เมื่อเร็ว ๆ นี้ฉันพบ update_post_thumbnail_cache ($ the_query) ขอขอบคุณสำหรับการชี้แจง
chifliiiii

4

คำถามนี้มีอายุมากกว่า 1 ปี แต่ฉันมี problomlem เท่ากันและนี่คือฟังก์ชั่นที่จะเพิ่ม meta_value และ meta_key แต่ละรายการให้กับวัตถุ $ wp_query

แทนที่จะค้นหาแต่ละโพสต์เมตาในขณะที่วนรอบฟังก์ชันนี้จะทำหนึ่งตัวอย่างการสืบค้นเพิ่มเติม:

"SELECT meta_key, meta_value, post_id จาก $ wpdb-> postmeta WHERE post_id ใน (1,2,3,4,5 ... )"

โดยที่ (1,2,3,4,5 ... ) ถูกระงับการโพสต์ ID จาก $ 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" จะถูกเขียนไปยังแต่ละ $ wp_query-> โพสต์ [$ i]

$wp_query->posts[0]->postmeta

ตัวอย่างเช่น 'someMetaKeyName' อย่าลืมใส่

add_query_meta() กับธีมของคุณ 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++;
    }
}

ฉันรักทางออกนี้
อาร์มสตรองที่

3

ฉันมีปัญหาที่คล้ายกันเมื่อเร็ว ๆ นี้ฉันต้องการเมตาดาต้า 7 ประเภทจากประเภทโพสต์ที่กำหนดเอง แต่ยังต้องได้รับโพสต์ตามเมทาดาทาอีกด้วย

ดังนั้นฉันจึงสร้างคำสั่ง SQL ต่อไปนี้ฉันมักจะใช้มัน หวังว่ามันจะช่วยให้คนอื่น ฉันจะพยายามอธิบายให้ดีที่สุดเท่าที่จะทำได้

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

ก่อนอื่นฉันจะได้รับฟังก์ชั่นฐานข้อมูลเวิร์ดเพรสด้วย $ wpdb ทั่วโลก จากนั้นฉันตั้ง posttype ด้วย $ pt ในการรับโพสต์ที่ถูกต้องที่ตรงกับค่าเฉพาะใน post_meta ฉันตั้งค่า $ mk (meta_key)

จากนั้นฉันตั้งค่า $ mv (meta_value) var (ในกรณีนี้ค่าเมตาตรงกับ postid)

$ mk1- $ mk7 เป็น meta_keys ที่ฉันต้องการจากโพสต์แต่ละรายการ (ฉันจะคว้าค่าในคำสั่งเลือก)

ฉันยังสร้าง 'สั่งซื้อโดย' a var ด้วยการตั้งค่า $ ord

คำสั่ง select จะเป็นดังนี้: ฉันเลือกรหัสโพสต์และ post_title จาก POST หรือ 'p'

จากนั้นฉันเลือกเมทาดาทาทั้งหมดที่ฉันต้องเลือกด้วย pm1 -> pm.7 และคว้า meta_value และเปลี่ยนชื่อ (AS) เพื่อให้สามารถอ่านได้มากขึ้นเมื่อดึงข้อมูลจากวัตถุของฉัน

ฉันสร้าง LEFT JOIN สำหรับข้อมูลเมตาที่ฉันต้องการให้ตรงกับโพสต์ (PM)

ฉันสร้างการรวม 7 ซ้ายสำหรับข้อมูลเมตาแต่ละรายการที่ฉันต้องดึง (PM1-pm7)

คำสั่ง WHERE ขึ้นอยู่กับ LEFT JOIN แรก (PM) เพื่อที่จะรู้ว่าฉันต้องการเฉพาะโพสต์ที่เมตาดาต้าตรงกันเท่านั้น

ฉันยังเพิ่ม 'และ' สำหรับประเภทโพสต์และสำหรับ post_statuses ที่ไม่ใช่ฉบับร่าง (ดังนั้นโพสต์ที่เผยแพร่เท่านั้น)

ในที่สุดฉันก็เพิ่มประโยค 'สั่งซื้อโดย'

สิ่งนี้ใช้ได้อย่างรวดเร็วและมีดัชนีในตัวใน Wordpress ดังนั้นจึงดูเหมือนมีประสิทธิภาพ

ไม่รู้ว่ามีอะไรดีไปกว่านี้หรือไม่ แต่ถ้าเป็นฉันก็อยากจะใช้

หวังว่านี่จะช่วยได้

มาร์คัส


ขอบคุณโพสต์นี้มีประโยชน์มาก ฉันสร้างมุมมองที่มีเขตข้อมูลเมตาทั้งหมดที่ฉันต้องการและตอนนี้รวดเร็วและง่ายต่อการรับข้อมูลใด ๆ ที่ฉันต้องการ
Liko

0

เฮ้โปรดลองอันนี้ฉันคิดว่ามันใช้ได้ดี

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

    $query = new WP_Query( $args );

อะไรคือเหตุผลที่คุณใช้meta_keyและmeta_query[]['key']เช่นกัน?
ไกเซอร์

1
ไม่สิ่งนี้ใช้ไม่ได้และนำอาร์เรย์ของโพสต์กลับมาโดยไม่ต้องใช้เมตาที่เกี่ยวข้อง
YemSalat

3
meta_keyและ / หรือmeta_queryไม่ปรับเปลี่ยนประเภทของผลลัพธ์ที่ส่งคืนเฉพาะแบบสอบถามเอง
BODA82
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.