Wp_query có thể trả lại meta bài viết trong một yêu cầu không?


22

Tôi muốn tạo một wp_query sẽ trả về meta bài viết bên trong postsmảng.

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

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

Điều này trả về một cái gì đó như:

nhập mô tả hình ảnh ở đây

Như bạn có thể thấy các bài đăng không có bất kỳ dữ liệu meta nào, có thể bao gồm dữ liệu meta trong mảng được trả lại không?

PS Tôi không muốn thêm wp_queries vì ​​lý do hiệu suất.


2
WP_Query chuẩn không trả về dữ liệu meta bài viết. Các tùy chọn duy nhất bạn có là: 1) chạy get_post_metatrên các khóa riêng lẻ, 2) chạy get_post_customđể nhận tất cả các trường tùy chỉnh bài đăng trong một lần chụp hoặc 3) tạo truy vấn của riêng bạn bằng cách sử dụng lớp $ wpdb ( get_results()) để xây dựng đối tượng trả về của riêng bạn . (tài liệu lớp $ wpdb: codex.wordpress.org/Class_Reference/wpdb )
BODA82

Câu trả lời:


20

Theo mặc định, WP_Querytrả về các WP_Postđối tượng tiêu chuẩn cho các bài đăng được truy vấn. Tôi tin rằng với một số cách viết lại thông minh và sử dụng các bộ lọc được cung cấp trong WP_Querybạn có thể thêm các đối tượng vào WP_Postmảng các đối tượng được trả về .

Đây sẽ là biểu diễn? Theo tôi, nó sẽ ảnh hưởng đến hiệu suất nhiều hơn vì bạn sẽ cần tham gia kết quả vào truy vấn của mình vì các trường tùy chỉnh không được lưu trong wp_postsbảng, nhưng trong wp_postmetabảng

Truy xuất meta bài đăng thực sự nhanh chóng và nó không yêu cầu thêm bất kỳ trường hợp nào WP_Query. Bạn chỉ có thể gọi trường tùy chỉnh với get_post_meta(). WordPress đã rất chu đáo khi các lĩnh vực tùy chỉnh được giới thiệu. Họ đã thêm một bộ đệm để lưu trữ chúng, vì vậy cho dù bạn đang truy vấn 1 hoặc 100 trường tùy chỉnh, bạn sẽ truy cập cơ sở dữ liệu một lần, cực nhanh. Đối với một bài kiểm tra và giải thích đầy đủ, xem bài đăng này tôi đã thực hiện gần đây về chủ đề này.

Theo tôi, cuộc gọi cơ sở dữ liệu bổ sung và thời gian thực tế sử dụng là đáng giá và nhanh hơn so với viết lại WP_Querytheo cách để bao gồm các trường tùy chỉnh trong đối tượng bài tiêu chuẩn được trả về bởi$posts


OK, cảm ơn, tôi sẽ chọn cái này như được chấp nhận, nhưng thành thật mà nói, nó rất rắc rối khi gọi get_post_meta()cho mỗi bài đăng .. Tôi muốn có một cách để lưu trữ dữ liệu bổ sung trực tiếp trong wp_postsbảng hoặc trong một bảng liên quan không nhiều như một mindf * ck wp_postsmeta.
YemSalat

Vâng, thành thật mà nói, cho dù gọi get_post_meta()hoặc nó như là một đối tượng bài viết, bạn sẽ cần phải gọi nó trên mỗi bài viết. Nó giống với các thẻ mẫu như the_content(), bạn phải gọi nó trên mỗi bài đăng.
Pieter Goosen

2
Điều này có nghĩa là nếu bạn phải hiển thị 120 bài đăng, bạn sẽ có thêm 120 truy vấn trong trang của mình?
chifliiiii

Tất cả các postdata được lưu trong bộ nhớ cache, vì vậy bạn sẽ không có thêm truy vấn nào khi sử dụng meta bài đăng
Pieter Goosen

Bạn đúng rồi. Tôi đã đề cập đến post_thumbnails nhưng gần đây tôi đã tìm thấy update_post_thumbnail_cache ($ the_query). Dù sao cũng cảm ơn vì đã làm rõ
chifliiiii

4

Câu hỏi này đã hơn 1 năm tuổi, nhưng tôi có cùng một vấn đề, và đây là chức năng sẽ thêm từng meta_value và meta_key vào đối tượng $ wp_query,

thay vì truy vấn mỗi meta bài đăng trong vòng lặp while, hàm này sẽ thực hiện thêm một ví dụ truy vấn:

"CHỌN meta_key, meta_value, post_id TỪ $ wpdb-> postmeta WHERE post_id IN (1,2,3,4,5 ...)"

trong đó (1,2,3,4,5 ...) hiện đang truy vấn ID bài đăng từ $ 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" sẽ được viết cho mỗi $ wp_query-> bài viết [$ i]

$wp_query->posts[0]->postmeta

Ví dụ với 'someMetaKeyName' đừng quên đặt

add_query_meta() đến chủ đề của bạn funcin.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++;
    }
}

Tôi thích giải pháp này.
Armstrongest

3

Gần đây tôi có một vấn đề tương tự, tôi cần lấy 7 mẩu siêu dữ liệu từ một loại bài đăng tùy chỉnh, nhưng cũng cần để có được bài đăng dựa trên một mẩu siêu dữ liệu.

Vì vậy, tôi đã tạo ra câu lệnh SQL sau đây, tôi sử dụng nó thường xuyên. Hy vọng nó sẽ giúp được người khác. Tôi sẽ cố gắng giải thích nó tốt nhất có thể.

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

Đầu tiên tôi nhận các hàm cơ sở dữ liệu wordpress với toàn cầu $ wpdb. Sau đó, tôi đặt posttype với $ pt. Để có được bài đăng chính xác phù hợp với một giá trị cụ thể trong post_meta, tôi đặt $ mk (meta_key)

Sau đó, tôi đặt var $ mv (meta_value). (trong trường hợp này giá trị meta khớp với một postid)

$ mk1- $ mk7 là meta_key tôi muốn từ mỗi bài đăng. (Tôi sẽ lấy các giá trị trong câu lệnh chọn)

Tôi cũng thực hiện 'order by' một var, bằng cách đặt $ ord

Câu lệnh select diễn ra như sau: Tôi chọn ID bài đăng và post_title từ POST hoặc 'p.'

Sau đó, tôi chọn tất cả các siêu dữ liệu tôi cần chọn chúng với pm1. -> pm.7 và lấy meta_value và đổi tên chúng (AS) để dễ đọc hơn khi lấy dữ liệu từ đối tượng của tôi.

Tôi tạo một THAM GIA TRÁI PHIẾU cho dữ liệu meta tôi cần để khớp với bài viết. (PM)

Tôi tạo 7 liên kết trái cho mỗi dữ liệu meta tôi cần truy xuất. (pm1-pm7)

Câu lệnh WHERE dựa trên LEFT THAM GIA đầu tiên (chiều) để nó sẽ biết tôi chỉ cần các bài đăng có siêu dữ liệu khớp.

Tôi cũng thêm một 'VÀ' cho loại bài đăng và cho các post_statuses không phải là bản nháp. (vì vậy chỉ có bài viết được xuất bản)

Cuối cùng tôi thêm mệnh đề 'order by'.

Điều này hoạt động nhanh và với các chỉ mục tích hợp trong Wordpress, vì vậy nó có vẻ hiệu quả.

Không biết có thứ gì tốt hơn cái này không, nhưng nếu có, tôi rất thích sử dụng nó.

Hi vọng điêu nay co ich.

Marcus


Cảm ơn, bài viết này rất hữu ích. Tôi đã tạo một chế độ xem với tất cả các trường meta tôi cần và bây giờ rất nhanh và dễ dàng để có được bất kỳ dữ liệu nào tôi muốn
Liko

0

Xin hãy thử cái này tôi nghĩ nó hoạt động tốt.

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

    $query = new WP_Query( $args );

Lý do mà bạn sử dụng là gì meta_keymeta_query[]['key']cũng?
kaiser

1
Không, điều này không hoạt động và mang lại mảng bài đăng mà không có meta liên quan đến chúng.
YemSalat

3
meta_keyvà / hoặc meta_querykhông sửa đổi loại kết quả trả về, chỉ chính truy vấn đó.
BODA82
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.