• Resolved PGrizz

    (@pgrizz)


    Greetings,

    We’re trying to get Relevanssi to put result priority on pages with titles that contain the search term in the very start of the title.

    For example, if “Dark Souls” is searched (without the “”), it produces the results: 1) Dark Souls II: Scholar of the First Sin, 2) Bleach: Dark Souls, 3) Dark Souls III, 4) Dark Fall: Lost Souls, 5) Dark Souls II.

    Since #2 “Bleach: Dark Souls” and #4 “Dark Fall: Lost Souls” don’t contain “Dark Souls” at the start of the page title, we would like these two pages to have a lower priority and titles that start with “Dark Souls” such as #3 and #5 to be displayed before these two results.

    Searching “Dark Souls” with the “” changes the order slightly, but still doesn’t solve this problem and still puts “Dark Fall: Lost Souls” as result #3 before “Dark Souls II” and other titles that begin with the “Dark Souls” search term.

    I have “AND – require all terms” set with Disable OR fallback. Relevance as the Default order, and 100 weight put on Post titles with 0 weight applied to Comment, Tag, and Category.

    I also tried using the Boost Exact Title Matches functions.php code provided by https://www.relevanssi.com/knowledge-base/adding-extra-boost-exact-title-matches/ but that also doesn’t seem to correct this problem.

    How can we make sure that every page title that starts with “Dark Souls” is put first in our results? Also, is it possible to take this a step further where it better organizes how the I, II, III or 1, 2, 3 at the end of the titles are also ordered numerically?

    https://www.ads-software.com/plugins/relevanssi/

Viewing 11 replies - 1 through 11 (of 11 total)
  • Plugin Author Mikko Saari

    (@msaari)

    Use the relevanssi_hits_filter filter hook to manipulate the results. It gives you full control over the results, and you can use it to put the start of the title matches first and put them in alphabetical order.

    Here are some examples to show you how the filter works.

    Thread Starter PGrizz

    (@pgrizz)

    Hey Mikko,

    Thanks for the quick response! In your link I see how to sort by alphabetical order which kind of works using:

    add_filter('relevanssi_modify_wp_query', 'rlv_sort_by_title');
    function rlv_sort_by_title($q) {
    	$q->set('orderby', 'post_title');
    	$q->set('order', 'asc');
    	return $q;
    }

    But I don’t see how to also put priority on the first part of the post/page’s title.

    For example, using the above code, now it displays as 1) Bleach: Dark Souls, 2) Dark Fall: Lost Souls, 3) Dark Souls II, 4) Dark Souls III, 5) Dark Souls: Prepare to Die Edition.

    We’re looking for it to display with priority on titles that begin with “Dark Souls” THEN sorting those titles alphabetically like: 1) Dark Souls: Prepare to Die Edition, 2) Dark Souls II, 3) Dark Souls III, 4) Bleach: Dark Souls, 5) Dark Fall: Lost Souls.

    Am I missing something in the guide or is this something more custom we need to create on our own? If more custom, can you help explain a little more how we could achieve this?

    Plugin Author Mikko Saari

    (@msaari)

    Use the relevanssi_hits_filter – there are examples on the page I linked to, so you can see how the filter works. It gives you an array of all the search results, and you can then reorder the results as you wish.

    Use the first example (“Sorting by category”) as the base, but instead of using the category to pick some posts to a different array, take the posts that have titles that start with the search query. Something like this:

    add_filter('relevanssi_hits_filter', 'title_matches_first', 10, 2);
    function title_matches_first($hits, $query) {
    	$title_matches = array();
    	$everything_else = array();
    	foreach ($hits[0] as $hit) {
    		$title_match = false;
    		if (strtolower(substr($post->post_title, 0, strlen($query)) == strtolower($query)) {
    			$title_match = true;
    		}
    		$title_match ? array_push($title_matches, $hit) : array_push($everything_else, $hit);
    	}
    
    	$hits[0] = array_merge($title_matches, $everything_else);
    	return $hits;
    }

    Something like this.

    Thread Starter PGrizz

    (@pgrizz)

    Hmm, starting to follow, but I believe that this line is breaking the code and functions file.

    if (strtolower(substr($post->post_title, 0, strlen($query)) == strtolower($query)) {

    Plugin Author Mikko Saari

    (@msaari)

    It’s missing a closing parentheses:

    if (strtolower(substr($post->post_title, 0, strlen($query))) == strtolower($query)) {

    Thread Starter PGrizz

    (@pgrizz)

    Yep, that fixes the code, but adding this code doesn’t seem to change anything and we get the same Relevanssi results with or without the code added. ??

    1) Dark Souls II: Scholar of the First Sin, 2) Bleach: Dark Souls, 3) Dark Souls III

    Don’t think I’m doing anything wrong because the Search by Post Title code works correctly and sorts A-Z.

    Plugin Author Mikko Saari

    (@msaari)

    That code was from the top of my head, here’s the same code now that I tested how it works:

    add_filter('relevanssi_hits_filter', 'title_matches_first');
    function title_matches_first($hits) {
    	$title_matches = array();
    	$everything_else = array();
    	$query = $hits[1];
    	foreach ($hits[0] as $hit) {
    		$title_match = false;
    		if (strtolower(substr($hit->post_title, 0, strlen($query))) == strtolower($query)) {
    			$title_match = true;
    		}
    		$title_match ? array_push($title_matches, $hit) : array_push($everything_else, $hit);
    	}
    
    	$hits[0] = array_merge($title_matches, $everything_else);
    	return $hits;
    }
    Thread Starter PGrizz

    (@pgrizz)

    Yep, that did the trick!

    Thanks for taking the time to make a great plugin and constantly support it via the forums. ??

    Thread Starter PGrizz

    (@pgrizz)

    Actually, sorry, there’s still one minor issue. ??

    These are the results for “Dark Souls” we’re getting now that aren’t in numerical order:

    1) Dark Souls II: Scholar of the First Sin
    2) Dark Souls III
    3) Dark Souls II
    4) Dark Souls: Prepare to Die Edition

    or alternatively searching “Gears of War” produces:

    1) Gears of War 3
    2) Gears of War 4
    3) Gears of War: Ultimate Edition
    4) Gears of War 2

    What would be the best way to edit the functions file to still display based on the start of post title but also display in order of No Name, II or 2, III or 3, and so on — like this:

    1) Dark Souls: Prepare to Die Edition
    2) Dark Souls II
    3) Dark Souls II: Scholar of the First Sin
    4) Dark Souls III

    We do something similar in Python with a table that first assigns each roman numeral to a number such as I = 1 and IV = 4 then adds the values and converts to an integer and some other magic that subtracts the totals and appends the numerals which is probably way too complicated and we can’t get it to work anyways with Relevanssi… hoping you could suggest a better solution.

    Plugin Author Mikko Saari

    (@msaari)

    Well, you have the posts in the $title_matches array, so if you just sort the array before it’s merged here:

    $hits[0] = array_merge($title_matches, $everything_else);

    then the results will be sorted correctly. You need to create a custom sorting function, as you’re sorting objects by their $hit->post_title field.

    I’ll leave figuring out the correct sorting method as an exercise for you. Here’s how you sort the table:

    usort($title_matches, 'game_title_cmp');

    Then you also need the sorting function:

    function game_title_cmp($a, $b) {
        if ($a->post_title == $b->post_title) return 0;
        return ($a->post_title < $b->post_title) ? -1 : 1;
    }

    This should do a plain alphabetical sorting; adding more intelligence to it is up to you.

    Thread Starter PGrizz

    (@pgrizz)

    Thanks again, Mikko! That helped get the job done. ??

Viewing 11 replies - 1 through 11 (of 11 total)
  • The topic ‘Set Results to Display Exact Matches From Start of Page Titles First?’ is closed to new replies.