wp_queryは単一のリクエストで投稿メタを返すことができますか?


22

posts配列内に投稿メタを返すwp_queryを作成したいと思います。

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

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

これは次のようなものを返します:

ここに画像の説明を入力してください

投稿にメタデータがないことがわかるように、返された配列にもメタデータを含めることは可能ですか?

PSパフォーマンス上の理由から、追加のwp_queriesは必要ありません。


2
標準のWP_Queryは、投稿のメタデータを返しません。唯一のオプションは、1)get_post_meta個々のキーで実行、2)get_post_customすべての投稿カスタムフィールドを1回で取得、または3)$ wpdbクラスを使用して独自のクエリを作成(get_results())して独自の戻り値オブジェクトを作成。($ wpdbクラスのドキュメント:codex.wordpress.org/Class_Reference/wpdb
BODA82 14

回答:


20

デフォルトでWP_Queryは、WP_Postクエリされている投稿の標準オブジェクトを返します。私はいくつかの巧妙な書き直しと、与えられたフィルターの使用によりWP_Query、返されたWP_Postオブジェクト配列にオブジェクトを追加できると信じています。

これはパフォーマンスになりますか?私の意見では、カスタムフィールドが保存されていないとして、あなたのクエリで結果を結合するために必要になるので、より多くのパフォーマンスを傷つけるwp_postsテーブルが、で、wp_postmetaテーブル

ポストメタの取得は非常に高速で、の追加インスタンスは必要ありませんWP_Query。を使用して、単純にカスタムフィールドを呼び出すことができget_post_meta()ます。カスタムフィールドが導入されたとき、WordPressは非常に思慮深いものでした。それらはキャッシュするためにキャッシュを追加したので、1つまたは100のカスタムフィールドを照会している場合でも、データベースに1回、非常に高速でアクセスしています。完全なテストと説明については、このテーマで最近行ったこの投稿を参照してください。

私の意見では、余分なデータベース呼び出しと実際に費やされた時間は価値があり、WP_Query返される標準の投稿オブジェクトにカスタムフィールドを含めるように書き換えるよりも速くなります$posts


わかりました、ありがとう、私はこれを受け入れられたものとして選びますが、正直なところ、get_post_meta()すべての単一の投稿を呼び出すのは非常に面倒です。私はむしろ、wp_postsテーブルに直接、または関連するテーブルは、mindf * ckほどではありませんwp_postsmeta
YemSalat 14

まあ、正直に言うと、呼び出しget_post_meta()またはそれを投稿オブジェクトとして、あなたはすべての投稿でそれを呼び出す必要があります。のようなテンプレートタグでも同じthe_content()です。すべての投稿で呼び出す必要があります。
ピーターグースン14

2
これは、120件の投稿を表示する必要がある場合、ページにさらに120件のクエリがあることを意味しますか?
chifliiiii

すべてのポストデータはキャッシュに保存されるため、ポストメタを調整するときに余分なクエリはありません
Pieter Goosen

あなたが正しいです。私はpost_thumbnailsを参照していましたが、最近update_post_thumbnail_cache($ the_query)を見つけました。とにかく説明をありがとう
-chifliiiii

4

この質問は1年以上前のものですが、私は同じ問題を抱えています。ここに、各meta_valueとmeta_keyを$ wp_queryオブジェクトに追加する関数があります。

whileループで各投稿メタを照会する代わりに、この関数は1つの追加の照会例を実行します。

「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++;
    }
}

このソリューションが大好きです。
アームストロング

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で設定します。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)、オブジェクトからデータを取得するときに読みやすくします。

投稿に一致させる必要があるメタデータのLEFT JOINを作成します。(午後)

取得する必要のあるメタデータごとに7つの左結合を作成します。(pm1-pm7)

WHEREステートメントは最初のLEFT JOIN(pm)に基づいているため、メタデータが一致する投稿のみが必要であることがわかります。

また、投稿タイプと下書きではないpost_statusesに「AND」を追加します。(したがって、公開された投稿のみ)

最後に、「order by」句を追加します。

これは高速で動作し、Wordpressの組み込みインデックスで機能するため、効率的です。

これよりも優れているかどうかはわかりませんが、優れている場合は使用したいと思います。

お役に立てれば。

マーカス


おかげで、この投稿は非常に役立ちます。私は私が必要とするすべてのメタフィールドを持つビューを作成し、現在、非常に速く、私が望む任意のデータを取得するのは簡単です
リコ

0

ちょっとこれを試してみてください。うまくいくと思います。

$args = array(
            'post_type' => 'page',
            'meta_key' => 'someMetaKeyName',
            'meta_query' => array(
                array(
                        'key' => 'someMetaKeyName',
                        'type' => 'CHAR',
                   ),
                ),
        );

    $query = new WP_Query( $args );

あなたが使用している理由は何だmeta_keymeta_query[]['key']同様に?
カイザー14

1
いいえ、これは機能せず、メタが関連付けられていない投稿の配列を戻します。
YemSalat 14

3
meta_keyおよび/またはmeta_query、返される結果のタイプを変更せず、クエリのみを変更します。
BODA82 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.