web-dev-qa-db-ja.com

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

posts配列の中にpostsメタを返すようなwp_queryを作成したいと思います。

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

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

これは次のようになります。

enter image description here

ご覧のとおり、投稿にはメタデータがありませんが、返された配列にもメタデータを含めることは可能ですか。

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

20
YemSalat

デフォルトでは、 WP_Query は照会されている投稿の標準の WP_Post オブジェクトを返します。私は、WP_Queryで与えられたフィルタの巧妙な書き換えと使用であなたが返されたWP_Postオブジェクト配列にオブジェクトを追加できると思います。

これはパフォーマンスですか?私の考えでは、カスタムフィールドはwp_postsテーブルではなくwp_postmetaテーブルに保存されるため、クエリで結果を結合する必要があるため、パフォーマンスがさらに低下します。

投稿メタの取得は本当に高速で、追加のWP_Queryインスタンスを必要としません。カスタムフィールドは get_post_meta() で呼び出すことができます。カスタムフィールドが導入されたとき、WordPressは非常に慎重でした。それらはそれらをキャッシュするためにキャッシュを追加しました、それであなたが1つか100のカスタムフィールドを質問しているかどうか、あなたは一度、超高速でデータベースを打っています。完全なテストと説明については、 この記事を参照してください 私は最近この問題についてやっています。

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

20
Pieter Goosen

私は最近同様の問題を抱えていました、私はカスタム投稿タイプから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 );

まず、WordPressのデータベース関数をグローバル$ wpdbで取得します。それから私は$ ptでポストタイプを設定しました。 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に組み込まれているインデックスで動作するので、効率的に見えます。

何かがこれより優れているかどうかわからないが、もしそれが良ければ、私はそれを使用したいと思います。

お役に立てれば。

マーカス

4
Marcus

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

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

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

追加の "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
Jonny

ちょっとこれを試してください私はそれがうまくいくと思います。

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

    $query = new WP_Query( $args );
0
Amit Mishra