获取自定义字段键的所有值(跨发布)


44

我知道如何获取特定帖子的自定义字段值。

get_post_meta($post_id, $key, $single);

我需要的是让所有与特定的自定义后键关联,该值在所有的帖子

有人知道这样做的有效方法吗?我不想遍历数据库中的所有帖子ID。

例:

4个帖子的自定义字段“ Mood”的值均不同。2个帖子的值为“ happy”,1个帖子的值为“ angry”,1个帖子的值为“ sad”

我想输出:在我们所有的帖子中:两个快乐,一个愤怒和一个悲伤的作者。

但是很多职位。

我正在寻找的是:

  • 一个WP函数来获得这个。要么
  • 一个自定义查询,以使其尽可能高效地获得。

5
似乎您将其用作分类法。为什么不在保存时简单地(自动)在这些帖子中添加术语?使查询变得容易得多。
kaiser

@kaiser我非常感谢您成为天才!
user2128576 '16

Answers:


58

一种可能的方法是使用WPDB类中的辅助方法之一来执行更精细的基于元的查询。但是,使用其中一些功能的警告是,即使您只需要调用一列或一行,通常也不需要获取简单的数据数组,并且通常不必对对象属性进行不必要的引用。

当然,并非所有功能都是相同的,WPDB方法是有目的的提及,该方法get_col返回了所查询数据的简单平面数组,我之所以特别提及,是因为以下示例将调用此方法。

WordPress-WPDB选择数据列
$ wpdb-> get_col()

这是一个示例函数,该函数在数据库中查询所选帖子类型,帖子状态以及特定元键(或技术性较差的自定义字段)的所有帖子。

function get_meta_values( $key = '', $type = 'post', $status = 'publish' ) {

    global $wpdb;

    if( empty( $key ) )
        return;

    $r = $wpdb->get_col( $wpdb->prepare( "
        SELECT pm.meta_value FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = %s 
        AND p.post_status = %s 
        AND p.post_type = %s
    ", $key, $status, $type ) );

    return $r;
}

因此,例如,如果您想找出哪些帖子具有“ 等级”的元键,那么对于该帖子类型的电影,并且您希望将该信息存储在变量中,则可以使用这样的调用示例。

$movie_ratings = get_meta_values( 'rating', 'movies' );

如果您只想将数据打印到屏幕上,PHP的implode函数可以将简单的数组快速拼接成数据行。

// Print the meta values seperate by a line break
echo implode( '<br />', get_meta_values( 'YOURKEY' ));

您还可以使用返回的数据来计算出多少个具有这些元值的帖子,例如,对返回的数据进行简单的循环并构建计数数组。

$movie_ratings = get_meta_values( 'rating', 'movies' );
if( !empty( $movie_ratings ) ) {
    $num_of_ratings = array();
    foreach( $movie_ratings as $meta_value )
        $num_of_ratings[$meta_value] = ( isset( $num_of_ratings[$meta_value] ) ) ? $num_of_ratings[$meta_value] + 1 : 1;
}

/*
Result:
Array(
    [5] => 10
    [9] => 2
)
// ie. there are 10 movie posts with a rating of 5 and 2 movie posts with a rating of 9.
*/

该逻辑可以应用于各种数据,并可以扩展为以多种不同方式工作。因此,我希望我的示例对您有所帮助,并且简单易懂。


3
如果您只想提取“唯一”元值,则对于以后的查看者也很有趣-您DISTINCT可以在SELECT上面的函数中的紧随其后键入。可能有用。
Howdy_McGee

我认为这非常有用
Pablo SG Pacheco

如何做到这一点,并返回排序后的值?,我认为使用ORDER by但我无法弄清楚如何使用它
efirvida 18-4-17的

14

我只想在上面t31os的代码中添加一个小东西。我自己使用此代码时,将“ SELECT”更改为“ SELECT DISTINCT”以消除重复的条目。


1
我可以想象有多个具有相同值的元值是有效的情况,因此没有在我的代码中添加该值。如果您想要独特的价值,那将是您的最佳选择。另外,您还可以将其添加为函数的参数(因此,可以根据需要使用或不使用它)。
t31os 2014年

10

使用全局$ wpdb不好或不需要:

// function to grab all possible meta values of the chosen meta key.
function get_meta_values( $meta_key,  $post_type = 'post' ) {

    $posts = get_posts(
        array(
            'post_type' => $post_type,
            'meta_key' => $meta_key,
            'posts_per_page' => -1,
        )
    );

    $meta_values = array();
    foreach( $posts as $post ) {
        $meta_values[] = get_post_meta( $post->ID, $meta_key, true );
    }

    return $meta_values;

}

$meta_values = get_meta_values( $meta_key, $post_type );

在大多数情况下,这是我首选的方法。它会进行五个查询,而不仅仅是一个查询,但是,由于它使用标准的WordPress过程生成和提交查询,因此任何特定于平台的缓存(例如WP Engine的对象缓存或某些随机插件)都会加入。数据也在请求期间将其存储在WordPress的内部缓存中,因此如果需要,无需再次从数据库中检索。
Andrew Dinmore

任何过滤器也将应用于数据,这在例如多语言站点上可能非常重要。最后,由于它仅使用标准的WordPress核心功能,因此以后更新的可能性很小。
Andrew Dinmore

4

最快的方法是自定义sql查询,我不确定,但是您可以尝试

$wpdb->get_results("
  SELECT posts.* , COUNT(*) 'moodcount'
  FROM $wpdb->posts as posts
  JOIN $wpdb->postmeta as postmeta
  ON postmeta.post_id = posts.ID
  AND postmeta.meta_key = 'Mood'
  GROUP BY postmeta.meta_key
");

如果有的话,那就开始了。


1
谢谢,但是是否应该“不惜一切代价”避免自定义查询?我宁愿使用WP抽象层(是,它叫什么?)...但当然,如果这是不可能的..
mikkelbreum

如果以正确的方式编写自定义查询,则可能会更好,并且只有在不知道自己在做什么的情况下才应避免使用它们。
Bainternet 2011年

1
我MWB .custom查询同意是非常有用的,实用的,但我认为他们也都对DB重得多。特别是使用SRT功能..
krembo99

3

用于通过meta键获取所有meta值

检查WP-> DB Wordpress Codex

$values = $wpdb->get_col("SELECT meta_value
    FROM $wpdb->postmeta WHERE meta_key = 'yourmetakey'" );

3
这种方法的问题是缺乏特异性,您将从这种查询中获得大量结果,其中可能包括草稿,已删除邮件,帖子,页面以及任何其他现有的帖子类型。您永远不应查询不需要的内容,在这里肯定需要特定性。
t31os 2014年

虽然确实可以从其他帖子类型和状态获取值,但是有时候您所需要的只是值,并且除了需要的地方没有使用过meta_key。如果所有/大多数值都是唯一的,则这可能是最佳解决方案。
卢克·吉迪恩

2

没有理由不能将t31os和Bainternet的代码合并为一个可重用的准备好的语句(wordpress样式),该语句在一次有效的操作中返回计数和值。

这是一个自定义查询,但仍在使用wordpress数据库抽象层-因此,例如,表名到底是什么或它们是否更改都无关紧要,并且它是预先准备好的语句,因此我们可以免受SQL攻击等的危害。 。

在这种情况下,我不再检查帖子类型,而是排除空字符串:

    $r = $wpdb->get_results(  $wpdb->prepare( "
        SELECT pm.meta_value AS name, count(*) AS count  FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = '%s'
        AND pm.meta_value != '' 
        AND p.post_type = '%s'
        GROUP BY pm.meta_value
        ORDER BY pm.meta_value          
        ", $key, $type) 
        );
    return $r;

特别是

这将返回一个对象数组,如下所示:

array  
 0 => 
 object(stdClass)[359]
  public 'name' => string 'Hamish' (length=6)
  public 'count' => string '3' (length=1)
 1 => 
 object(stdClass)[360]
  public 'name' => string 'Ida' (length=11)
  public 'count' => string '1' (length=1)
 2 => 
 object(stdClass)[361]
  public 'name' => string 'John' (length=12)
  public 'count' => string '1' (length=1)

0

将以下内容与foreach一起使用

 $key = get_post_custom_values( 'key' );

假设您的自定义字段键的名称为


请注意,如果未指定post_id,则默认为当前帖子。
birgire
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.