我想创建一个wp_query,该查询将返回posts数组内的帖子元。

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

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


这将返回以下内容: />
如您所见,帖子没有任何元数据,是否有可能将元数据也包含在返回的数组中?由于性能原因。

评论

标准WP_Query不返回帖子元数据。您唯一的选择是:1)对单个键运行get_post_meta,2)运行get_post_custom以一枪获取所有帖子自定义字段,或3)使用$ wpdb类(get_results())创建自己的查询以建立自己的返回对象。 ($ wpdb类文档:codex.wordpress.org/Class_Reference/wpdb)

#1 楼

默认情况下,WP_Query返回所查询帖子的标准WP_Post对象。我相信通过巧妙地重写和使用WP_Query中提供的过滤器,您可以将对象添加到返回的WP_Post对象数组中。

这会表现吗?我认为,由于自定义字段未保存在wp_posts表中,但是在wp_postmeta表中保存了自定义字段,因此您需要在查询中加入结果,这会进一步损害性能。它不需要WP_Query的任何额外实例。您只需使用get_post_meta()调用自定义字段即可。引入自定义字段时,WordPress非常周到。他们添加了一个缓存来缓存它们,因此无论您要查询1个还是100个自定义字段,您都可以超快地访问数据库一次。有关完整的测试和解释,请参阅我最近在该主题上所做的这篇文章。在WP_Query返回的标准post对象中包括自定义字段的方法

评论


好的,谢谢,我会选择接受的一个,但是说​​实话,它为每个帖子都调用get_post_meta()这么麻烦。我宁愿有一种方法可以直接在wp_posts表中存储其他数据,或在相关表中使用,而不像wp_postsmeta那样。

– YemSalat
2014年12月12日下午4:57

好吧,说实话,无论是调用get_post_meta()还是将其作为post对象,您都需要在每个post上都调用它。与模板标签(例如the_content())相同,您必须在每个帖子上都调用它。

–Pieter Goosen
2014年12月12日下午5:02

这意味着,如果您必须显示120个帖子,那么您的页面中还会有120个查询?

– chifliiiii
2015年9月14日19:25在

所有后置数据都保存在缓存中,因此在计算后置元数据时您将不会有额外的查询

–Pieter Goosen
2015年9月14日19:27在

你是对的。我指的是post_thumbnails,但最近发现了update_post_thumbnail_cache($ the_query)。仍然感谢您的澄清

– chifliiiii
2015年9月14日19:50

#2 楼

这个问题已经有1年多的历史了,但是我有同样的问题,这里的函数会将每个meta_value和meta_key添加到$ wp_query对象,此函数将执行一个额外的查询
示例:

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


将在每个$ wp_query-> posts [$ i]中写入附加的“ postmeta” [$ 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++;
    }
}


评论


我喜欢这个解决方案。

–最强
17年8月1日在15:29

#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设置为posttype。与post_meta中的特定值匹配的帖子,我设置了$ mk(meta_key)

然后我设置了$ mv(meta_value)变量。 (在这种情况下,元值匹配一个postid)。

$ mk1- $ mk7是我希望从每个帖子中获取的meta_keys。 (我将在select语句中获取值)

我还通过设置$ ord

将'order by'设为变量,select语句如下:
我从POST或“ p”中选择帖子ID和post_title。

然后选择所有需要用pm1选择它们的元数据。 -> pm.7并获取meta_value并重命名它们(AS),这样从我的对象中检索数据时它更具可读性。发布。 (pm)

我为需要检索的每个元数据创建7个左联接。 (pm1-pm7)

WHERE语句基于第一个LEFT JOIN(pm),因此它将知道我只需要元数据匹配的帖子。

我还要为帖子类型和非草稿的post_statuses添加“ AND”。 (因此只有已发布的帖子)

最后我添加了“ order by”子句。

不知道是否有比这更好的东西,但是如果是,我很乐意使用它。

希望有帮助。

马库斯

评论


谢谢,这篇文章非常有帮助。我创建了一个包含我需要的所有元字段的视图,现在可以非常轻松快捷地获取我想要的任何数据

–丽高
17年11月23日在12:01

#4 楼

嘿请尝试一下,我认为它可以正常使用。

$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']的原因是什么?

– kaiser
2014年12月12日下午3:56

不,这是行不通的,它会返回没有与元相关联的帖子数组。

– YemSalat
2014年12月12日下午3:57

meta_key和/或meta_query不会修改返回的结果的类型,只会修改查询本身。

– BODA82
2014年12月12日下午4:39