Answers:
默认情况下,WP_Query
返回WP_Post
要查询的帖子的标准对象。我相信通过巧妙地重写和使用给定的过滤器,WP_Query
可以将对象添加到返回的WP_Post
对象数组中。
这会表现吗?我认为,这将进一步降低性能,因为您需要在查询中加入结果,因为自定义字段未保存在wp_posts
表中,而是在wp_postmeta
表中
检索post meta确实非常快,并且不需要任何额外的实例WP_Query
。您只需使用即可调用自定义字段get_post_meta()
。引入自定义字段时,WordPress非常周到。他们添加了一个缓存来缓存它们,因此无论您要查询1个还是100个自定义字段,您都可以超快地访问数据库一次。有关完整的测试和解释,请参阅我最近在该主题上发表的这篇文章。
在我看来,额外的数据库调用和实际花费的时间是值得的,并且比WP_Query
以将自定义字段包括在由以下方法返回的标准post对象中的方式进行重写要快$posts
get_post_meta()
为每一个职位..我宁愿有要么直接在存储附加数据的方式wp_posts
表,或在相关表,并不是那么容易wp_postsmeta
。
get_post_meta()
它还是将其作为帖子对象,您都需要在每个帖子中对其进行调用。模板标记(例如)也是如此the_content()
,您必须在每个帖子中都调用它。
这个问题已有1年多的历史了,但是我有同样的问题,这里是将每个meta_value和meta_key添加到$ wp_query对象的函数,
该函数将执行一个额外的查询示例,而不是在while循环中查询每个帖子元。
“从$ wpdb-> postmeta中选择meta_key,meta_value,post_id,在post_id中输入(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设置posttype。为了获得与post_meta中的特定值匹配的正确帖子,我设置了$ mk(meta_key)
然后设置$ mv(meta_value)变量。(在这种情况下,元值与postid相匹配)
$ mk1- $ mk7是我希望从每个帖子中获取的meta_keys。(我将在select语句中获取值)
我还通过设置$ ord使'order by'为var
select语句如下:我从POST或“ p”中选择帖子ID和post_title。
然后,选择所有需要使用pm1选择的元数据。-> pm.7并获取meta_value并重命名它们(AS),以便从我的对象中检索数据时它更具可读性。
我为需要与帖子匹配的元数据创建了一个LEFT JOIN。(下午)
我为需要检索的每个元数据创建了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)