Sort by Wordpress by Relevance

I created a fairly advanced search for the Wordpress site that I am working on atm. Allowing visitors to filter the results by various taxonomy, sort them by date or custom fields, as well as a normal free text search (which WP offers by default).

I accomplished this with the pre_get_posts filter and just adding my material to the request, something like this: (note that I did not consider some health checks and other code)

 <?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'); } } 

Now I would like to add another way to sort messages, namely by relevance. I understand that this is a very common request, and most of the solutions to the problem that I have seen include using the Relevanssi plugin. Seeing how I already wrote my own โ€œpluginโ€ (well, at least the code), and I have all my search forms and lists configured to use it, switching to Relevanssi will not be too simple at the moment.

Sooo, I would like to know if anyone knows of a (preferred) easy way to add this with the code that I already have?

As far as I understand, WP performs a search using LIKE instead of MATCH() , and therefore it does not even have a relevancy score for sorting. If this is correct, I assume that I have to write my own query at all? How can I do this without messing up the breakdown of WP, etc.? Or I can add something like $qry->set('WHERE', "MATCH(post_content) AGAINST('$q' IN BOOLEAN MODE) AS relevance"); $qry->set('sortby', 'relevance') $qry->set('WHERE', "MATCH(post_content) AGAINST('$q' IN BOOLEAN MODE) AS relevance"); $qry->set('sortby', 'relevance') , do you think?

+6
source share
2 answers

Ok, so I ended up using Relevanssi. But with some changes.

First of all, filtering on taxonomies was pretty simple, since it was built into Relevanssi, all I had to do was change the names of my <select> elements to the names of the taxonomy + change the values โ€‹โ€‹to bullets:

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

Secondly, to sort by a custom field, I had to use the relevanssi_hits_filter filter. Unlike pre_get_posts or relevanssi_modify_wp_query (which Sheikh Khera kindly suggested), this filter receives an array of messages, not a WP_Query object. When I tried to use the WP_Query object, the order just didn't change. Here's basically how to make your own look using 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; } 

It also helped with a previous problem that I had in that messages that did not have a price key were not displayed in the search results. Now they do, and the reason I give them the price of "10,000,000" is because they appear after those who have a price.

Finally, I also needed an empty search . According to Relevanssi dev, this is only supported in the Premium version, but I think I managed to get around this. At first I got WP to display the search page, even if? S was empty:

 <?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; } 

Secondly, I told Relevanssi to get all the messages if? s was empty, by default it will not receive any records at all. Unfortunately, the default behavior with custom taxonomies stopped working (my code wrote it), so I had to manually check the taxonomy in this code:

 <?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; } 

What is it. Everything seems to work, and hopefully this helps someone who has similar queries in the future.

I really hope WP improves its ridiculous search in the future. Sorting by relevance should be what is available in the world, the most popular CMS imo.

Thanks to @Sheikh Heera for pointing me in the right direction. I am not sure who should give the correct answer, although I saw how I really could not use the material that you proposed.

+4
source

I think you can use Relevanssi without any problems, but you need to use a hook filter , check attributeanssi_modify_wp_query for more details, check the following code

 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'); 

I tested this code and worked great. In this example, I used the 'restaurant' and 'products' custom message types, and the search works very well, only relevant results. You can also use if php 5.3+

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

Also, if you use the Relevanssi plugin, you can use it to customize the post_type page instead ( $qry->set( 'post_type', array(...) ) ) in your functions.php file.

Scree snapshot below

enter image description here

+5
source

Source: https://habr.com/ru/post/949697/


All Articles