First of all, this is not the best way to do this. You’re now running the search three times: first comes the default WP_Query, then you do your own WP_Query, then you run the search with Relevanssi. Unless there’s a really good reason to do that, it would be best to just modify the default WP_Query with pre_get_posts instead of doing a new query in the search results template.
If you don’t want to modify this that much, you can cut one search off with this:
$args = array(
'post_type' => 'blog',
's' => $keyword,
'relevanssi' => true,
);
...
$the_query = new WP_Query( $args );
This way you don’t need to run relevanssi_do_query(), and you only run the search query twice.
Anyway, to your actual problem. Your code seems fine, and Relevanssi should respect order, orderby and tax_query. You’ve checked that the WP_Query is getting the correct arguments in $args? This function will show you the orderby value Relevanssi is using:
add_filter( 'relevanssi_orderby', function( $orderby ) { var_dump( "RELEVANSSI ORDERBY: $orderby" ); return $orderby; } );
Does this print out title or relevance?
Thanks for your help
The above problem is solved, but when I add the argument to $args in the code below, it seems to just return the default results.
$args['post__in'] = $rating;
$args['orderby'] = 'post__in';
It doesn’t seem to work with post__in.
Relevanssi does not support post__in in orderby (post_name__in and post_parent__in aren’t supported, either). It’s just so rarely used that it hasn’t seemed like an important thing to add (you’re the first one to even mention it in 10+ years).
Relevanssi does give you lots of tools for ordering the results: you can use relevanssi_results or relevanssi_hits_filter to reorder the results any way you want to.
I am using a custom table instead of using a custom field. I found no other way to replace post__in.
Can you make an example for this filter?. i am using this code to get list of post ids.
function query_rating() {
global $wpdb;
$post_rating = $wpdb->get_results("SELECT id, rating FROM " . $wpdb->prefix . "blog" );
$rating = array_column($post_rating, 'rating');
array_multisort($rating, SORT_DESC, $post_rating);
$srating = array_column($post_rating, 'id');
return $srating;
}
I’m still quite confused as to how I should use the filter.
So you have ratings in the database and a higher rating comes first? Then it’s fairly simple: assign those ratings directly as weights for the posts:
add_filter( 'relevanssi_results', 'rlv_rating_weights' );
function rlv_rating_weights( $results ) {
global $wpdb;
$id_rating = $wpdb->get_results( "SELECT id, rating FROM {$wpdb->prefix}blog ORDER BY rating DESC", ARRAY_A );
$rating_by_id = array();
foreach ( $id_rating as $id => $rating ) {
$rating_by_id[ $id ] = $rating;
}
foreach ( array_keys( $results ) as $id ) {
$results[ $id ] = $rating_by_id[ $id ];
}
return $results;
}
Now Relevanssi weights are ignored, and instead is post gets the weight from the rating.
The code above doesn’t seem to work, the results are returned as the default search.
This is my database image.
https://i.imgur.com/DgdNdIY.png
I just wrote it, I didn’t test it. This one is tested:
add_filter( 'relevanssi_results', 'rlv_rating_weights' );
function rlv_rating_weights( $results ) {
global $wpdb;
$id_rating = $wpdb->get_results( "SELECT id, rating FROM {$wpdb->prefix}blog ORDER BY rating DESC", ARRAY_A );
$rating_by_id = array();
foreach ( $id_rating as $id_rating ) {
$rating_by_id[ $id_rating['id'] ] = floatval( $id_rating['rating'] );
}
foreach ( array_keys( $results ) as $id ) {
$results[ $id ] = $rating_by_id[ $id ];
}
return $results;
}