私はquery_brands_geo('dealers', 'publish', '1', $taxtype, $geo, $brands);
を介して私のtaxonomy.phpテンプレートで呼び出す次のクエリを持っています
この機能は完璧に機能します。しかし、クエリポストのためのコーデックスを読んだ後、それはデフォルトクエリを変更するための好ましい方法としてpre_get_postsを述べました。 pre_get_postsは下記のwp_query関数よりも効率的でしょうか?
もしそうなら、どうやってpre_get_postsを構築し、私の変数と以下のクエリを渡しますか?
function my_custom_query($posttype, $poststatus, $paidvalue, $taxtype, $geo, $brands) {
global $wp_query;
$wp_query = new WP_Query();
$args = array(
'post_type' => $posttype,
'post_status' => array($poststatus),
'orderby' => 'Rand',
'posts_per_page' => 30,
'meta_query' => array(
array(
'key' => 'wpcf-paid',
'value' => array($paidvalue),
'compare' => 'IN',
)
),
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => $taxtype,
'field' => 'slug',
'terms' => $geo
),
array(
'taxonomy' => 'brands',
'field' => 'slug',
'terms' => $brands
)
)
);
return $wp_query->query($args);
}
pre_get_posts
は同じクエリを実行するので、両方とも同じ時間がかかります。しかし、pre_get_posts
アクションを利用すると、1つ以上のSQLクエリを保存することになります。今のところ、WordPressはデフォルトクエリを実行しています。そして、デフォルトクエリの結果を置き換えるこの関数でクエリを実行します(結果として、デフォルトクエリは役に立ちません)。以下は、$args
をどのように移動するかです。
function custom_pre_get_posts($query, $posttype='dealers', $poststatus='publish', $paidvalue='1', $taxtype='any_default_value', $geo='any_default_value', $brands='any_default_value') {
// filter your request here.
if($query->is_category) {
$args = array(
'post_type' => $posttype,
'post_status' => array($poststatus),
'orderby' => 'Rand',
'posts_per_page' => 30,
'meta_query' => array(
array(
'key' => 'wpcf-paid',
'value' => array($paidvalue),
'compare' => 'IN',
)
),
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => $taxtype,
'field' => 'slug',
'terms' => $geo
),
array(
'taxonomy' => 'brands',
'field' => 'slug',
'terms' => $brands
)
)
);
$query->query_vars = $args;
}
}
add_action('pre_get_posts', 'custom_pre_get_posts');
最も支持された回答はクエリを中断し、いくつかの主要な点で単に真実ではないため、遅い回答です。
まず、WordPressは内部的にquery_posts()
を使用します(WP_Query
の薄いラッパーは使用しないでくださいテーマまたはプラグインで)WP_Query
を実行します。このWP_Query
はメインループ/クエリとして機能しています。このクエリは、実際のSQLクエリ文字列が構築されるまで、多くのフィルターとアクションを実行します。それらの1つはpre_get_posts
です。その他はposts_clauses
、posts_where
などです。これらはalsoクエリ文字列構築プロセスをインターセプトできます。
コア内部で何が起こるかを詳しく見る
WordPressは
wp()
関数(wp-includes/functions.php
内)を実行し、$wp->main()
を呼び出します($wp
はwp-includes/class-wp.php
で定義されているクラスWPのオブジェクトです)。これは、WordPressに次のことを伝えます。
WP->parse_request()
を使用してURLをクエリ仕様に解析します。詳細は以下をご覧ください。$wp_query->parse_query()
($wp_query
はclass WP_Query
のオブジェクトであり、wp-includes/query.php
で定義されています)を使用して、Conditional Tagで使用されるすべてのis_変数を設定します。この関数の名前にもかかわらず、この場合、WP_Query->parse_query
は実際には解析を行いません。これは、WP->parse_request()
によって事前に行われるためです。- 関数WP_Query-> get_posts()で、クエリ仕様をMySQLデータベースクエリに変換し、データベースクエリを実行して投稿のリストを取得します。 WordPressループで使用される投稿を$ wp_queryオブジェクトに保存します。
ソース Codex
メインクエリを本当に変更する場合は、さまざまなフィルターを使用できます。単に$query->set( 'some_key', 'some_value' );
を使用してchangeデータを使用するか、$query->get( 'some_key' );
を使用してretrieve条件付きチェックを行うデータ。これにより、SQLクエリのみalteringであるため、2番目のクエリを実行する必要がなくなります。
additionalクエリを実行する必要がある場合は、WP_Query
オブジェクトを使用します。これにより、DBに別のクエリが追加されます。
答えは例で常にうまく機能するので、ここであなたは本当に素晴らしいものを1つ手に入れました(Brad Touesnardの小道具)、それは単にコアオブジェクトを拡張し、したがってかなり再利用可能です(プラグインを作ります):
class My_Book_Query extends WP_Query
{
function __construct( $args = array() )
{
// Forced/default args
$args = array_merge( $args, array(
'posts_per_page' => -1
) );
add_filter( 'posts_fields', array( $this, 'posts_fields' ) );
parent::__construct( $args );
}
public function posts_fields( $sql )
{
return "{$sql}, {$GLOBALS['wpdb']->terms}.name AS 'book_category'";
}
}
その後、次の例に示すように、second/ additionalクエリを実行できます。後でクエリをリセットすることを忘れないでください。
$book_query = new My_Book_Query();
if ( $book_query->have_posts() )
{
while ( $book_query->have_posts() )
{
$book_query->the_post();
# ...do stuff...
} // endwhile;
wp_reset_postdata();
} // endif;
WP_query()、query_posts()およびpre_get_posts を使用する場合。
あなたが心に疑いを持っているならば、それは素晴らしいリソースです。