カスタムフィールドキーのすべての値の取得(クロスポスト)


44

特定の投稿のカスタムフィールド値を取得する方法を知っています。

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

必要なのは、すべての投稿にわたって、特定のカスタム投稿キーに関連付けられたすべての値を取得することです。

誰でもこれを行う効率的な方法を知っていますか?DB内のすべての投稿IDをループしたくありません。

例:

「ムード」と呼ばれるカスタムフィールドのすべての値が異なる4つの投稿。2つの投稿の値は「happy」、1つの投稿の値は「怒っている」、1つの投稿の値は「悲しい」です

出力したい:私たちが持っているすべての投稿で:2人の幸せな人、1人の怒っている人、1人の悲しい作者。

しかし、たくさんの投稿のために。

私が探しているのは次のいずれかです:

  • これを取得するWP関数。または
  • これを可能な限り効率的に取得するためのカスタムクエリ。

5
これを分類法として使用しているようです。保存するときにこれらの投稿に単純に(自動的に)用語を追加しないのはなぜですか?クエリがはるかに簡単になります。
カイザー

@kaiser天才であることを十分に感謝することはできません!
user2128576

回答:


58

可能なアプローチの1つは、WPDBクラスのヘルパーメソッドの1つを使用して、より洗練されたメタベースのクエリを実行することです。ただし、これらの関数の一部を使用する場合の注意点は、1つの列または行だけを呼び出す場合でも、通常は単純なデータ配列を取得せず、通常はオブジェクトプロパティへの不要な参照を作成する必要があることです。

もちろん、すべての機能が同じというわけではありません。また、WPDBメソッドに意図的な言及がget_colあります。WPDBメソッドは、照会されたデータの単純なフラット配列を返します。 。

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

これは非常に便利だと思う
パブロSGパチェコ

これを行うには、値を返す方法私は、ORDER BYを使用したが、私はそれを使用する方法を見つけ出すカントと思い?,ソート
efirvida

14

上記のt31osのコードにちょっとしたことを追加したいと思います。このコードを自分で使用したときに重複したエントリを削除するために、「SELECT」を「SELECT DISTINCT」に変更しました。


1
同じ値の複数のメタ値を持つことが有効であるため、コードにその追加を行わなかった場合を想像できます。個別の値が必要な場合は、これが方法です。さらに、それを関数の引数として追加することもできます(したがって、必要に応じて使用することも使用しないこともできます)。
t31os 14年

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

ほとんどの場合、これが私の推奨方法です。1つだけではなく5つのクエリを作成しますが、標準のWordPressプロシージャを使用してクエリを生成および送信するため、プラットフォーム固有のキャッシング(WPエンジンのオブジェクトキャッシングやランダムプラグインなど)が起動します。リクエストの間、WordPressの内部キャッシュに保存されるため、必要に応じてデータベースから再度取得する必要はありません。
アンドリューディンモア

フィルターもデータに適用されます。これは、多言語サイトなどで非常に重要になる可能性があります。最後に、標準のWordPressコア関数のみを使用しているため、将来の更新で破損する可能性ははるかに低くなります。
アンドリューディンモア

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

1
私はMWB .customクエリ..非常に便利かつ実用的ですが、私は、彼らがDBにもはるかに重いと思います..特にSRT機能を使用してに同意します
krembo99

3

メタキーによってすべてのメタ値を取得するため

wp-> db wordpress codexを確認してください

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

3
このアプローチの問題は、特異性の欠如です。下書き、ゴミ箱に入れられたアイテム、投稿、ページ、および存在する他の投稿タイプを含む可能性のあるクエリから多くの結果が得られます。必要のないものを照会することは絶対にしないでください。ここでは特に確実性が必要です。
t31os 14年

他の投稿タイプやステータスから値を取得できるのは事実ですが、必要なのは値だけであり、必要な場所以外ではmeta_keyを使用していない場合があります。すべて/ほとんどの値が一意である場合、これが最善の解決策である可能性があります。
ルークジェデオン

2

t31osとBainternetのコードを組み合わせて、1つの効率的な操作でカウントと値を返す再利用可能な準備済みステートメント(ワードプレススタイル)を作成できない理由はありません。

これはカスタムクエリですが、まだwordpressデータベース抽象化レイヤーを使用しています-たとえば、テーブル名が実際に何であるか、またはテーブル名が変更されているかどうかは関係ありません。 。

この例では、投稿タイプをチェックしなくなり、空の文字列を除外しています。

    $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が指定されていない場合、これはデフォルトで現在の投稿になります。
バージール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.