按相关性排序Wordpress搜索

pow*_*uoy 8 wordpress search relevance

我已经创建了一个非常高级的搜索我正在研究的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');
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我想添加另一种方式来对帖子进行排序,即通过相关性.我知道这是一个非常常见的请求,我遇到的问题的大多数解决方案都包括使用Relevanssi插件.看来我已经编写了自己的"插件"(好吧,代码至少)并且我的所有搜索表单和列表都设置为使用它,切换到Relevanssi在这一点上不会太容易.

Sooo,我想知道是否有人知道一些(最好)简单的方法来添加我已经获得的代码?

据我了解,WP使用LIKE而不是使用它进行搜索MATCH(),这就是为什么它甚至没有相关性得分可以排序.如果这是正确的,我假设我必须完全编写自己的查询?如何在不搞乱WP的分页等的情况下做到这一点?或者我可以添加类似$qry->set('WHERE', "MATCH(post_content) AGAINST('$q' IN BOOLEAN MODE) AS relevance"); $qry->set('sortby', 'relevance')你认为的东西吗?

The*_*pha 5

我认为您可以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');
Run Code Online (Sandbox Code Playgroud)

我已经测试了这段代码并且运行正常.在这个例子中我使用'restaurant''products'自定义帖子类型和搜索工作真的很好,只是相关的结果.你也可以使用if php 5.3+安装

add_filter('relevanssi_modify_wp_query', function($qry){
    // Same code
});
Run Code Online (Sandbox Code Playgroud)

此外,如果您使用Relevanssi插件,您可以使用它的设置页面来设置,post_type而不是$qry->set( 'post_type', array(...) )在您的functions.php文件中使用this().

Scree拍摄如下

在此输入图像描述


pow*_*uoy 4

好吧,我最终还是使用了 Relevanssi。但经过相当多的修改。

首先,分类法的过滤非常简单,因为这是内置在 Relevanssi 中的,我所需要做的就是将元素的名称更改<select>为分类法名称 + 将值更改为 slugs:

<select name="custom_taxonomy">
    <option value="some-term">Some term</option>
    ...
</select>
Run Code Online (Sandbox Code Playgroud)

其次,为了允许按自定义字段排序,我必须使用过滤relevanssi_hits_filter器。pre_get_posts与or (Sheikh Heera 善意建议的)不同relevanssi_modify_wp_query,此过滤器传递的是帖子数组,而不是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;
}
Run Code Online (Sandbox Code Playgroud)

这也解决了我之前遇到的问题,即缺少“价格”键的帖子没有出现在搜索中。现在他们这样做了,我给他们定价“10000000”的原因是为了让他们出现在那些有价格的人之后。

最后,我还需要空搜索才能工作。根据 Relevanssi 开发人员的说法,这只在高级版本中受支持,但我想我设法解决了这个问题。首先,即使 ?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;
}
Run Code Online (Sandbox Code Playgroud)

其次,我告诉 Relevanssi 如果 ?s 为空则获取所有帖子,默认情况下它根本不会获取任何帖子。不幸的是,在执行此操作时,自定义分类法的默认行为停止工作(我的代码重写了它),因此我还必须手动检查此代码中的分类法:

<?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;
}
Run Code Online (Sandbox Code Playgroud)

就是这样。一切似乎都有效,希望这对将来有类似请求的人有所帮助。

我真心希望 WP 能在未来改进它可笑的搜索。在我看来,按相关性排序应该是世界上最受欢迎的 CMS 中提供的功能。

感谢@Sheikh Heera 为我指明了正确的方向。我不知道该给谁正确的答案,因为我真的无法使用你建议的东西。