回答:
デフォルトで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
。
get_post_meta()
またはそれを投稿オブジェクトとして、あなたはすべての投稿でそれを呼び出す必要があります。のようなテンプレートタグでも同じthe_content()
です。すべての投稿で呼び出す必要があります。
この質問は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++;
}
}
最近、同様の問題が発生しました。カスタム投稿タイプから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の組み込みインデックスで機能するため、効率的です。
これよりも優れているかどうかはわかりませんが、優れている場合は使用したいと思います。
お役に立てれば。
マーカス
ちょっとこれを試してみてください。うまくいくと思います。
$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']
同様に?
meta_key
および/またはmeta_query
、返される結果のタイプを変更せず、クエリのみを変更します。
get_post_meta
個々のキーで実行、2)get_post_custom
すべての投稿カスタムフィールドを1回で取得、または3)$ wpdbクラスを使用して独自のクエリを作成(get_results()
)して独自の戻り値オブジェクトを作成。($ wpdbクラスのドキュメント:codex.wordpress.org/Class_Reference/wpdb)