WordPress.org

Forums

Search engine (4 posts)

  1. gate303
    Member
    Posted 9 years ago #

    I really need to know ho I am supposed to get the search engine to only search (or at least prioritize) whole words.

    When I (or my visitors) search for the word sea, they are probably not interested in "season" or "research"...

    How do I fix this? Is there any plugin?

  2. Pizdin Dim
    Member
    Posted 8 years ago #

    Either way, you'll have to hack the code.

    If you wanted to change the default WP behaviour, changing around 10 lines in /wp-includes/classes.php, from line 434 onwards:


    if (!$q['sentence']) {
    $s_array = explode(' ',$q['s']);
    $q['search_terms'] = $s_array;
    $search .= '((post_title LIKE \' '.$n.$s_array[0].$n.' \') OR (post_content LIKE \' '.$n.$s_array[0].$n.' \'))';
    for ( $i = 1; $i < count($s_array); $i = $i + 1) {
    $search .= ' AND ((post_title LIKE \' '.$n.$s_array[$i].$n.' \') OR (post_content LIKE \' '.$n.$s_array[$i].$n.' \'))';
    }
    $search .= ' OR (post_title LIKE \' '.$n.$q['s'].$n.' \') OR (post_content LIKE \' '.$n.$q['s'].$n.' \')';
    $search .= ')';
    } else {
    $search = ' AND ((post_title LIKE \' '.$n.$q['s'].$n.' \') OR (post_content LIKE \' '.$n.$q['s'].$n.' \'))';
    }

    The only change is to surround the $n variable with spaces. Keep in mind this has a shortcoming: it will never match posts where that word is the first or last one in the title or the content. And that's the reason WP search works the way it currently does.

    Something fancy like prioritising can't be done without extensive hacking of the code.

  3. Pizdin Dim
    Member
    Posted 8 years ago #

    Actually, now that I think about it some more, an alternate strategy could be to use the "REGEXP" operator instead of "LIKE", which when combined with a concept known as "word boundaries", could give you what you're after. So the same 10 lines of code would now look like this:


    if (!$q['sentence']) {
    $s_array = explode(' ', $q['s']);
    $q['search_terms'] = $s_array;
    $search .= '((post_title REGEXP \'[[:<:]]' . $s_array[0] . '[[:>:]]\') OR (post_content REGEXP \'[[:<:]]' . $s_array[0] . '[[:>:]]\'))';
    for ($i = 1; $i < count($s_array); $i = $i + 1) {
    $search .= ' AND ((post_title REGEXP \'[[:<:]]' . $s_array[$i] . '[[:>:]]\') OR (post_content REGEXP \'[[:<:]]' . $s_array[$i] . '[[:>:]]\'))';
    }
    $search .= ' OR (post_title REGEXP \'[[:<:]]' . $q['s'] . '[[:>:]]\') OR (post_content REGEXP \'[[:<:]]' . $q['s'] . '[[:>:]]\')';
    $search .= ')';
    } else {
    $search = ' AND ((post_title REGEXP \'[[:<:]]' . $q['s'] . '[[:>:]]\') OR (post_content REGEXP \'[[:<:]]' . $q['s'] . '[[:>:]]\'))';
    }

    For more info, see the regular expressions page in the MySQL manual. Just keep in mind that regular expressions are "more expensive", so if your site is very busy, it may not be worth it.

    P.S. My apologies to the board moderators who won't be pleased with me copying lots of code here.

  4. taksmith
    Member
    Posted 8 years ago #

    I had the same problem and got into real trouble editing the classes.php code with unclosed brackets appearing in the sql SELECT string. But, if all you want to do is seacrch for complete strings (in my case I wanted people's names - so didn't want to find all "fred" or "bloggs" - just "fred bloggs" then add the following to the searchform.php form

    <input type="hidden" value="1" name="sentence" id="sentence" />

    Then it doesn't break up the search string. If I was really clever and needed it I'm sure you could make this a checkbox to at least allow the option

Topic Closed

This topic has been closed to new replies.

About this Topic