답변:
기본적 으로 쿼리중인 게시물 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
.
get_post_meta()
포스트 오브젝트 든 솔직히 말하면, 모든 게시물에서 호출해야합니다. 같은 템플릿 태그와 동일 the_content()
하므로 모든 게시물에서 호출해야합니다.
이 질문은 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++;
}
}
최근 비슷한 문제가 발생하여 사용자 정의 게시물 유형에서 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의 내장 색인과 함께 빠르게 작동하므로 효율적입니다.
이보다 더 좋은 것이 있는지 모르겠지만, 있다면 더 사용하고 싶습니다.
이것이 도움이되기를 바랍니다.
마커스
이봐, 내가 잘 작동 생각합니다.
$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']
도는?
meta_key
및 / 또는 meta_query
결과의 유형 만 쿼리 자체를 반환 수정하지 마십시오.
get_post_meta
개별 키에서 실행, 2)get_post_custom
모든 게시물 사용자 정의 필드를 한 번에 가져 오거나 3) $ wpdb 클래스 (get_results()
)를 사용하여 고유 한 반환 객체를 작성하여 자체 쿼리 생성 . ($ wpdb 클래스 문서 : codex.wordpress.org/Class_Reference/wpdb )