0

私は、ターゲットアドレスからの距離順に入力された半径内の投稿タイプを表示するプロジェクトに取り組んでいます。今、私は正常に動作するこのクエリを使用しています:

sql = " SELECT SQL_CALC_FOUND_ROWS DISTINCT wposts.post_id, ( " . $_GET['mikm'] . " *           acos( cos( radians( $lat ) ) * cos( radians( wposts.lat ) ) * cos( radians( wposts.long ) - radians( $long ) ) + sin( radians( $lat ) ) * sin( radians( wposts.lat) ) ) )  AS distance  
    FROM post_address  wposts 
    WHERE wposts.post_type ='" . $post_type . "'
    HAVING distance <= $radius OR distance IS NULL ORDER BY distance LIMIT " . $from_page . "," . $per_page;


post_address は、投稿 ID、投稿タイプ、およびアドレスを保持するテーブルです。投稿がアドレスで保存または更新されると、このテーブルは情報で更新されます。私が使用するフォームには、住所のフィールド、マイルまたはキロメートルを選択するチェックボックス、およびドロップダウン メニューの距離があります。ページネーションのフォームで get メソッドを使用します。

上記のクエリは正常に機能しますが、分類法のサポートを追加しようとしています。私はそれを使用して1つの分類法で動作させることができました

wp_dropdown_categories($tax_name)


そしてSQL:

SELECT SQL_CALC_FOUND_ROWS DISTINCT wposts.post_id, ( " . $_GET['mikm'] . " * acos( cos( radians( $lat ) ) * cos( radians( wposts.lat ) ) * cos( radians( wposts.long ) - radians( $long ) ) + sin( radians( $lat ) ) * sin( radians( wposts.lat) ) ) )  AS distance  
FROM post_address  wposts
LEFT JOIN $wpdb->term_relationships ON (wposts.post_id = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
LEFT JOIN $wpdb->terms ON($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)
WHERE wposts.post_type ='" . $post_type . "'
AND $wpdb->term_taxonomy.taxonomy IN ('" $tax_name "')
AND ($wpdb->term_taxonomy.parent IN (" . $_GET[$tax_name] . ") OR $wpdb->term_taxonomy.term_id IN (" . $_GET[$tax_name] . "))
HAVING distance <= $radius OR distance IS NULL ORDER BY distance LIMIT " . $from_page . "," . $per_page;


今、1 つの分類法がうまく機能するので、複数の分類法で機能させたいと思っています。たとえば、投稿タイプ「車」に「モデル」と「色」の 2 つの分類法がある場合、「この」モデルと「この」色の投稿をフィルタリングできるようにしたいと考えています。投稿タイプにいくつの分類法が存在するかわかりません(このプラグインを使用する人は、管理者設定で手動で入力します)。それらは現在配列に保存されています。たとえば、$taxonomies = array('car_model','car_color') を使用すると、次を使用してカテゴリのドロップダウンを設定できます。

`
foreach ($taxonomies as $tax) {
echo     '<div id="' . $tax . '_cat">';
echo       '<label for="category-id">Choose category: </label>';
        custom_taxonomy_dropdown($tax); 
echo     '</div>';    
`



function custom_taxonomy_dropdown($tax_name) {
$args = array(
        'taxonomy'          => $tax_name,
        'hide_empty'        => 0,
        'depth'             => 10,
        'hierarchical'      =>  1,
        'id'                =>  $tax_name . '_id',
        'name'              => $tax_name,
        'selected'          => $_GET[$tax_name],
        'show_option_all'   => 'All categories',
        );      
wp_dropdown_categories($args); 
} 


ドロップダウンは正常に機能し、出力も url に送信されますが、それを機能させる SQL クエリを見つけることができません。

これは私の最初のプロジェクトです。この質問が長すぎる場合は申し訳ありませんが、できる限り明確にしようとしていました。上記のコードのいずれかが最善の方法であるかどうかもわかりませんが、誰からの助けも大歓迎です。

アップデート:

以下は私が現在使用しているコードで、複数の分類法で動作します。しかし、私はまだいくつかの問題を抱えています。すべての分類法で「すべてのカテゴリ」を選択すると、SQL は次のようになります。

AND $wpdb->term_taxonomy.term_id IN () 

カウントには count(*) = 0 が表示され、すべての結果ではなく結果が表示されません。

他の問題は、子と孫のカテゴリにあります。親カテゴリを選択すると、そのすべての子カテゴリと孫カテゴリの結果が得られると期待しています。しかし、親には投稿が添付されていませんが、その子カテゴリには投稿が添付されていないため、結果が得られません。これは私のコードです:

    "SELECT SQL_CALC_FOUND_ROWS DISTINCT wposts.post_id, (" . $_GET['mikm'] . "* acos( cos( radians( $lat ) ) * cos( radians( wposts.lat ) ) * cos( radians( wposts.long ) - radians( $long ) ) + sin( radians( $lat ) ) * sin( radians( wposts.lat) ) ) )  AS distance 
        FROM posts_address  wposts
        LEFT JOIN $wpdb->term_relationships ON (wposts.post_id = $wpdb->term_relationships.object_id)
        LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
        LEFT JOIN $wpdb->terms ON($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)
    WHERE 
    wposts.post_type IN ('" . $post_type . "')

    AND $wpdb->term_taxonomy.term_id IN (" . $total_terms .") 
    GROUP BY wposts.post_id, wposts.lat, wposts.long        
        HAVING count(*) = " . $bc . " AND distance <= $radius OR distance IS NULL ORDER BY distance LIMIT " . $from_page . "," . $per_page  ;

どんな助けでも感謝します。

4

1 に答える 1

0

私があなたの要件を正しく読んだ場合、データベースからタクソノミーに関する情報を抽出する必要はありません。投稿が必要なすべてのタクソノミーに「結合」していることを確認するだけです。必要なすべての分類法で投稿を結合し、行の乗算結果に基づいてフィルタリングします。

あなたが持っている最初のステップ

$wpdb->term_taxonomy.taxonomy IN ('" $tax_name "')

$wpdb->term_taxonomy.parent IN (" . $_GET[$tax_name] . ") OR $wpdb->term_taxonomy.term_id IN (" . $_GET[$tax_name] . "))

IN 演算子に入る引数が、引用符で囲まれたコンマ区切りのすべての分類名のリストを生成するようにします。例えば:

$wpdb->term_taxonomy.taxonomy IN ('model_a', 'color_blue')

これで、クエリは、投稿が一致するすべてのタクソノミー (フィルター内) で投稿を乗算します。ここからは簡単です: 投稿フィールドでグループ化し (クエリで出力したものだけでグループ化する必要があります)、HAVING を使用してフィルター処理し、すべてのカテゴリを乗算した投稿のみを返すようにします。この例では、投稿は 2 つのカテゴリに一致する必要があるため、次のようになります。

(...)
GROUP BY wposts.post_id, wposts.lat, wposts.long
HAVING count(*) = 2 AND (distance <= $radius OR distance IS NULL ORDER BY distance LIMIT " . $from_page . "," . $per_page);

count(*) フィルターは、一致した分類 "軸" の数と一致する必要があることに注意してください。また、分類法に衝突がないと仮定していることにも注意してください (つまり、「青」のモデルと「青」の色はありません)。

おそらく、クエリ内の DISTINCT 演算子を削除する必要があります (グループ化によって既に個別の投稿が生成されており、mysql のオプティマイザがいつ個別演算子を計算するのかわかりません)。

于 2012-04-25T02:16:53.133 に答える