8

atm で作業している Wordpress サイトのかなり高度な検索を作成しました。訪問者がさまざまな分類法で結果をフィルタリングし、日付またはカスタム フィールドで並べ替えたり、通常のフリー テキスト検索 (WP がデフォルトで提供) を実行したりできるようにします。

私はpre_get_postsフィルターを使用して、次のように自分のものをクエリに追加するだけでこれを達成しました: (いくつかのサニティチェックやその他のコードを省略していることに注意してください)

<?php
add_filter('pre_get_posts', 'my_search');

function my_search ($qry) {
    # Include more post types
    $qry->set('post_type', array('foo', 'bar'));

    if ($_GET['myorder'] == 'price') {
        $qry->set('orderby', 'meta_value_num');
        $qry->set('meta_key', 'price');
        $qry->set('order', 'ASC');
    }
    else {
        $qry->set('orderby', 'date');
        $qry->set('order', 'DESC');
    }
}

次に、投稿を並べ替える別の方法、つまり関連性を追加したいと思います。これは非常に一般的な要求であり、私が見た問題のほとんどの解決策には、Relevanssi プラグインの使用が含まれていることを理解しています。私はすでに独自の「プラグイン」(まあ、少なくともコード)を作成し、それを使用するようにすべての検索フォームとリストを設定しているため、この時点で Relevanssi に切り替えるのは簡単ではありません。

すっごく、私がすでに持っているコードでこれを追加する(できれば)簡単な方法を誰かが知っているかどうか知りたいですか?

私が理解している限り、WP はLIKE代わりに を使用して検索を行います。そのため、ソートする関連性スコアすらありMATCH()ません。これが正しければ、自分のクエリを完全に作成する必要があると思いますか? WPのページネーションなどを台無しにせずにこれを行うにはどうすればよいですか? または、あなたが推測するようなものを追加できますか?$qry->set('WHERE', "MATCH(post_content) AGAINST('$q' IN BOOLEAN MODE) AS relevance"); $qry->set('sortby', 'relevance')

4

3 に答える 3

4

Relevanssi問題なく使用できると思いますが、filterフックを使用する必要があります。詳細についてはrelevanssi_modify_wp_queryを確認し、次のコードを確認してください。

function func_reli($qry){
    $qry->set( 'post_type', array( 'post', 'page', 'restaurant', 'products' ) );

    if ($_GET['myorder'] == 'price') {
        $qry->set('orderby', 'meta_value_num');
        $qry->set('meta_key', 'price');
        $qry->set('order', 'ASC');
    }
    else {
        $qry->set('orderby', 'date');
        $qry->set('order', 'DESC'); // <-- set (in your code 'add' is used)
    }
    return $qry; // <-- must return, in your code you didn't
}
add_filter('relevanssi_modify_wp_query', 'func_reli');

このコードをテストしましたが、問題なく動作します。この例では、カスタム投稿タイプと検索を使用'restaurant''products'ましたが、関連する結果だけが表示されます。php 5.3+がインストールされている場合にも使用できます

add_filter('relevanssi_modify_wp_query', function($qry){
    // Same code
});

また、Relevanssiプラグインを使用する場合は、ファイルでこの ( )post_typeを使用する代わりに、そのセットアップ ページを使用して設定できます。$qry->set( 'post_type', array(...) )functions.php

以下のスクリーンショット

ここに画像の説明を入力

于 2013-07-20T20:04:49.303 に答える
4

結局、Relevanssi を使用することになりました。しかし、かなりの数の変更があります。

まず、タクソノミーのフィルタリングは Relevanssi に組み込まれているため非常に簡単でした。<select>要素の名前をタクソノミー名に変更し、値をスラッグに変更するだけで済みました。

<select name="custom_taxonomy">
    <option value="some-term">Some term</option>
    ...
</select>

次に、カスタム フィールドによる並べ替えを可能にするために、relevanssi_hits_filterフィルターを使用する必要がありました。pre_get_postsor relevanssi_modify_wp_query(Sheikh Heera が親切に提案した)とは異なり、このフィルターはWP_Query オブジェクトではなく、投稿の配列を渡します。WP_Query オブジェクトを使用しようとすると、順序の変更が拒否されました。基本的に、独自の並べ替えを行う方法は次のrelevanssi_hits_filterとおりです。

<?php
add_filter('relevanssi_hits_filter', 'h5b_hits_filter');

function h5b_hits_filter ($hits) {
    global $wp_query;

    if (isset($wp_query->query_vars['orderby']) and $wp_query->query_vars['orderby'] == 'price') {
        if (count($hits[0])) {
            usort($hits[0], 'h5b_sort_by_price');
        }
    }

    return $hits;
}

function h5b_sort_by_price ($a, $b) {
    $priceKey   = 'price';
    $aPrice     = get_post_meta($a->ID, $priceKey, true);
    $bPrice     = get_post_meta($b->ID, $priceKey, true);
    $aPrice     = $aPrice ? $aPrice : 10000000;
    $bPrice     = $bPrice ? $bPrice : 10000000;

    if ($aPrice == $bPrice) {
        return 0;
    }

    return ($aPrice < $bPrice) ? -1 : 1;
}

これは、「価格」キーのない投稿が検索に表示されないという以前の問題にも役立ちました。今ではそうです。私が「10000000」という価格を付けたのは、価格があるものの後に表示されるようにするためです。

最後に、空の検索を機能させる必要もありました。Relevanssi dev によると、これは Premium バージョンでのみサポートされていますが、私はそれを回避できたと思います。最初に、?s が空の場合でも WP に検索ページを表示させました。

<?php
add_filter('request', 'h5b_allow_empty_search');

function h5b_allow_empty_search ($qryVars) {
    if (isset($_GET['s']) and empty($_GET['s'])) {
        $qryVars['s'] = ' ';
    }

    return $qryVars;
}

次に、?s が空の場合はすべての投稿を取得するように Relevanssi に指示しました。デフォルトでは、投稿はまったく取得されません。残念ながら、これを行うと、カスタム分類法でのデフォルトの動作が機能しなくなった (私のコードが上書きした) ため、このコードでも分類法を手動で確認する必要がありました。

<?php
add_filter('relevanssi_hits_filter', 'h5b_allow_empty_search_filter');

function h5b_allow_empty_search_filter ($hits) {
    if (isset($_GET['s']) and empty($_GET['s']) and !count($hits[0])) {
        $taxQry = array('relation' => 'AND');

        if (!empty($_GET['custom_taxonomy'])) {
            $taxQry[] = array(
                'taxonomy' => 'custom_taxonomy', 
                'field' => 'slug', 
                'terms' => $_GET['custom_taxonomy']
            );
        }

        $args = array(
            'numberposts' => -1, 
            'post_type' => 'any'
        );

        if (count($taxQry) > 1) {
            $args['tax_query'] = $taxQry;
        }

        $hits[0] = get_posts($args);
    }

    return $hits;
}

以上です。すべてが機能しているようで、うまくいけば、これは将来同様の要求を持つ人を助けるでしょう.

WP が将来的にばかげた検索を改善することを本当に願っています。関連性による並べ替えは、世界で最も人気のある CMS imo で利用できるものであるべきです。

私を正しい方向に向けてくれた@Sheikh Heeraに感謝します。あなたが提案したものを本当に使用できなかったので、誰に正しい答えを与えるべきかわかりません.

于 2013-07-23T01:11:37.843 に答える