wp_query가 단일 요청으로 게시물 메타를 반환 할 수 있습니까?


22

posts배열 내부의 게시물 메타를 반환하는 wp_query를 만들고 싶습니다 .

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

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

이것은 다음과 같은 것을 반환합니다 :

여기에 이미지 설명을 입력하십시오

게시물에 메타 데이터가없는 것을 볼 수 있듯이 반환 된 배열에도 메타 데이터를 포함시킬 수 있습니까?

추신 : 성능상의 이유로 추가 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테이블에 직접 또는 추가 데이터를 저장하는 방법이있었습니다 . 관련 표만큼 많지 않은 관련 테이블 wp_postsmeta.
YemSalat

글쎄요, 전화를 걸든 get_post_meta()포스트 오브젝트 든 솔직히 말하면, 모든 게시물에서 호출해야합니다. 같은 템플릿 태그와 동일 the_content()하므로 모든 게시물에서 호출해야합니다.
Pieter Goosen

2
즉, 120 개의 게시물을 표시해야하는 경우 페이지에 추가로 120 개의 검색어가 있습니까?
chifliiiii

당신이 추가 문의 사항이되지 않도록 모든 POSTDATA는 캐시에 저장받을 때 칼, 링 포스트 메타
피터 구센

네 말이 맞아 post_thumbnails를 언급하고 있었지만 최근에 update_post_thumbnail_cache ($ the_query)를 발견했습니다. 어쨌든 설명을 주셔서 감사합니다
chifliiiii

4

이 질문은 1 세 이상이지만 동일한 problomlem이 있으며 $ wp_query 객체에 각 meta_value 및 meta_key를 추가하는 함수가 있습니다.

while 루프에서 각 게시물 메타를 쿼리하는 대신이 함수는 하나의 추가 쿼리 예제를 수행합니다.

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

여기서 (1,2,3,4,5 ...)는 $ wp_query에서 현재 게시 된 ID를 정복했습니다.

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

추가 "postmeta"는 각 $ wp_query-> posts [$ 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++;
    }
}

나는이 솔루션을 좋아한다.
Armstrongest

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로 wordpress 데이터베이스 기능을 얻습니다. 그런 다음 $ pt로 포스트 유형을 설정했습니다. post_meta의 특정 값과 일치하는 올바른 게시물을 얻으려면 $ mk (meta_key)를 설정하십시오.

그런 다음 $ mv (meta_value) var를 설정했습니다. (이 경우 메타 값은 postid와 일치합니다)

$ mk1- $ mk7은 각 게시물에서 원하는 meta_keys입니다. (select 문에서 값을 가져옵니다)

나는 또한 $ ord를 설정하여 var에 'order by'를 만든다

select 문은 다음과 같습니다. POST 또는 'p'에서 게시물 ID와 post_title을 선택합니다.

그런 다음 pm1로 선택해야하는 모든 메타 데이터를 선택합니다. -> pm.7으로 meta_value를 가져 와서 이름을 바꾸면 (AS) 객체에서 데이터를 검색 할 때 더 읽기 쉽습니다.

게시물과 일치 해야하는 메타 데이터에 대해 왼쪽 조인을 만듭니다. (오후)

검색해야 할 각 메타 데이터마다 7 개의 왼쪽 조인을 만듭니다. (pm1-pm7)

WHERE 문은 첫 번째 LEFT JOIN (pm)을 기반으로하므로 메타 데이터가 일치하는 게시물 만 필요하다는 것을 알 수 있습니다.

또한 게시물 유형 및 초안이 아닌 post_statuses에 'AND'를 추가합니다. (따라서 게시 된 게시물 만)

마지막으로 'order by'절을 추가합니다.

이것은 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_keymeta_query[]['key']도는?
카이저

1
아니요,이 기능은 작동하지 않으며 연결된 메타가없는 게시물 배열을 다시 가져옵니다.
YemSalat

3
meta_key및 / 또는 meta_query결과의 유형 만 쿼리 자체를 반환 수정하지 마십시오.
BODA82
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.