Posted on

Sorting search results

If you want something else than the default relevancy ranking, you can use orderby and order parameters for the search query. Orderby accepts $post variable attributes and order can be asc (ascending) or desc (descending). The most relevant attributes here are most likely post_date and comment_count.

If you want to give your users the ability to sort search results by date, add something like this to your search results page:

<?php echo '<p><a href="' . get_bloginfo('url') . '?s=' . get_search_query() . '&orderby=post_date&order=desc">Order results by date<a></p>'; ?>

Order by relevance is either orderby=relevance or no orderby parameter at all.

36 comments Sorting search results

    1. Not using orderby, but you can use relevanssi_hits_filter to organize the results in any order you wish. If you want it to be triggered by users, you can add a new query variable (for example “sort_order”) and check for that. If “sort_order=1”, order by custom fields ascending, if “sort_order=2”, order by custom fields descending and so on.

  1. Sorting appears to work well for single blog sites, but when using it on a WP-MS site the sort parameter has no effect. An example query I’m trying is:
    http://example.com/news?s=myterm&searchblogs=1%2C2%2C3%2C4%2C5%2C6&orderby=post_date&order=asc

    If I delete the &searchblogs=.. then it works fine. Any ideas?

    I’m still on 1.5.7 (if it’s not broken, don’t fix it :)), but haven’t seen anything in the release notes to suggest this is the issue?

    1. Multiblog searching doesn’t support sorting. Only query variable it supports at the moment is post_type. I didn’t implement most of the things single site search does, because they are a lot more complicated, but I suppose adding support for sorting wouldn’t be too tricky.

  2. Hey there,

    I have a search page set up and that shows search results – fine. I would like to add a link/button to this page that will sort the results by meta_values OR taxonomy terms.

    For example – If I had a meta_key called ‘Year’ – and the values were 2001, 2002, 2003 etc…I would like to order them starting with the oldest first.

    I tried using ‘&meta_key=year&orderby=meta_value&order=ASC’ but it seems to have no effect.

    Would meta_keys or taxonomies be best for this? What is the easiest way to do this?

    Hope that makes sense and thanks for your help!

    1. That won’t work, orderby only accepts values that are wp_posts database table columns.

      Sorting by taxonomies or custom fields can be done, I guess, but it’s a bit more complicated. You would need to use relevanssi_hits_filter to intercept the results and put them in the order you want to – but then you could have any order whatsoever you want.

      1. Thank you for the quick reply Mikko! How would I go about using the relevanssi_hits_filter? Do you have some example code that I could look at please? I don’t quite understand how to get it to work.

        Once I have this feature enabled, my site will be perfect! Thanks again for your help.

  3. Something like this:

    add_filter('relevanssi_hits_filter', 'order_the_results');
    function order_the_results($hits) {
        global $wp_query;
        if ($wp_query->query_vars['orderby'] == 'meta_year') {
            $years = array();
            foreach ($hits[0] as $hit) {
            	$year = get_post_meta($hit->ID, 'Year', true);
            	if (!isset($years[$year])) $years[$year] = array();
            	array_push($years[$year], $hit);
            }
            ksort($years);
            $sorted_hits = array();
            foreach ($years as $year => $year_hits) {
            	$sorted_hits = array_merge($sorted_hits, $year_hits);
            }
            $hits[0] = $sorted_hits;
        }
        return $hits;
    }
  4. I think I understand.

    Shouldn’t “if ($wp_query->query_vars[‘orderby’] == ‘meta_year’) {” be “if ($wp_query->query_vars[‘orderby’] == ‘meta_VALUE’) {” ??

    If I add this to the functions.php, how do I call the function on the link/button on the search results page to reorder the results?

    Would it be something like <a href="”>Order by Year ?

    Thank you!

  5. Right, now I understand. However I do get these warnings when trying to run the link:

    Warning: Attempt to assign property of non-object in —domain— /relevanssi.php on line 1010

    Warning: Attempt to assign property of non-object in —domain— /relevanssi.php on line 1018

    Warning: array_map() [function.array-map]: Argument #2 should be an array in —domain— /wp-includes/post.php on line 1676

    Warning: array_keys() [function.array-keys]: The first argument should be an array in —domain— /wp-includes/post.php on line 1634

    Warning: Invalid argument supplied for foreach() in —domain— /wp-includes/post.php on line 1634

    And this warning shows up in the results section:

    Warning: Invalid argument supplied for foreach() in —domain— /themes/db/functions.php on line 165 (the “foreach ($hits as $hit) {” line from the function)

    Any ideas? Sorry to be a pain with all this (there’s a donation on the way once I can get it working!)

    Thanks

  6. I made a mistake in the code and corrected it in the example, but looks like you were quick enough to grab the first version. That line should be “foreach ($hits[0] as $hit) {“.

  7. The first lot of warnings are gone, and the results are now in the correct order! 😀

    I still get the “invalid argument supplied for foreach() in —domain— /themes/db/functions.php on line 165” in the results section though (one for each result).

    If these warning could be fixed, it would then be complete!

    1. I’ve implemented the code shown here, and it works great! Only I’m not sure how to use it to reverse the order of the sort? Simply adding “order=DESC” and such doesn’t work, as I thought.

      1. The code shown in the example is already sorting in descending order, so in order to reverse it, you need to change “order=desc” to “order=asc”.

        1. I was just using desc as an example, neither of the directions seem to work. Here’s the site in question:

          http://www.needforbead.com/?s=arcade

          If you click on the “Beads” header, it appropriately sorts the beads from smallest to largest, however if you click on it again (the header is coded to show the opposite direction of whatever is currently set), it will add order=ASC to the URL with no effect.

          1. If you sort by post_title or post_date, sorting works both ways. Where is the number of beads stored? Because Relevanssi can only sort by it if it’s stored in the $post, that is it’s a column in the wp_posts database. If it is in a custom field, then Relevanssi can’t sort by it.

  8. I found it! I had an ‘order_the_results’ reference in the search.php (left from a previous test).

    IT NOW WORKS! WOOHOO!

    Thank you so much for your help. You have saved me a lot of headaches and time, much appreciated!

  9. The beads are indeed a custom field, but if it’s able to sort this in one direction, reversing that direction should be pretty simple, shouldn’t it?

      1. Alright. I switched the this plugin originally not for the relevant sort necessarily but how comprehensive the results were, as well as the ability to search tags and custom fields as well. It is worlds ahead of the default WordPress search. I dread toying with the thought of returning to it… So I guess the search for a solution continues! Regardless, the plugin works great and thanks for the quick responses!

        1. There’s a way with Relevanssi, it’s just slightly more complicated than adding one query parameter. The solution involves some PHP code and using the relevanssi_hits_filter filter hook. See here.

          Essentially, you need to create a function that checks if the order and orderby parameters are set and which then sorts the results by the desired custom field. It’s not particularly tricky.

  10. This got me on the right track.

    In my case, I needed to sort either by the date of an event or the published date. So this code creates a custom meta field called ‘searchdate’ that is saved on each post and page save.

    I can then use the query var orderby=searchdate to search the term. I also needed the ordering changed, so this includes the code to handle ordering either ‘asc’ or ‘desc’.

    Like most things, pretty simple once you’ve done it 🙂

    http://pastebin.com/g5eUTAHk

      1. Ah, thank you Mikko! By any chance do you know the difference between using ‘title’ vs “post_title” is? I know the latter is what relevanssi requires, but the WordPress docs for WP_query list “title” only.

        1. Relevanssi actually understands both now. The orderby parameters should match the database column names, and the database column is called “post_title”. (You can sort by any wp_posts database column.)

          1. is there anything in settings that would prevent the orderby from not working with the following?

            $argsTest = array(
            ‘post_type’ =>’post’,
            ‘orderby’ => ‘post_title’,
            ‘order’ => ‘asc’,
            ‘posts_per_page’ => 8,
            ‘s’ => ‘harmony documents’,
            );

            I alternate order => ‘desc’ or ‘DESC’ or ‘asc’ or ‘ASC’ with no sorting taking place. Thanks again this is the last piece of my puzzle.

          2. It should work like that. If you remove the orderby, does the order alone have any effect on results? Do other orderings work, for example ‘post_date’? Are you sure the results you’re seeing are coming from Relevanssi?

          3. Hey, The order alone has no effect on the results. No other orderings work except my relevanssi_hits_filter seem to be working. I am certain the results are coming form Relevanssi. Quick note I just found out i’m on Relevanssi Pro 1.9. Also Taxonomy and Terms don’t seem to be working properly any thoughts on this?

            ‘post_type’ => ‘post’,
            ‘order’ => ‘DESC’,
            ‘posts_per_page’ => 8,
            ‘paged’ => 0,
            ‘s’ => ‘Harmony documents’,
            ‘taxonomy’ => ‘publications|Terms’,
            ‘terms’ => ‘harmony-documents|harmony-documents-original-language’,

          4. Can you show me the whole code you’re using to call the search? Put it in a pastebin, for example.

            I would recommend updating to 1.10.12. 1.9 is already pretty old.

          5. Yes, just subscribe. New versions support tax_query. It’s hard to say why the sorting doesn’t work – it should, and your code seems correct. I’d throw in some var_dump()’s in the Relevanssi code to see that everything gets passed to Relevanssi alright.

Leave a Reply

Your email address will not be published. Required fields are marked *