Sunday, April 20, 2014
   
Text Size
Login

Improve Default Joomla Search


- Applies to Joomla 2.5.x +

What?
So I can't stand the way the default "Search" component in Joomla works. The default is to sort the results by popularity (hits) which I have never seen in any other system.

I've googled and binged but could not find anything that documents how to bring it into line with other search systems. So here we go, hope this helps you.


Why?
I've created search systems for a plethora of other systems. The aim of this article is to enhance the Joomla search into par with Google and Wikipedia (or near enough).


How?
I'd like to use various techniques, and the first part of this article (Stage 1) is the only part you need to modify as this will improve your Joomla search results by giving priority to articles where the search term is in the article title.

In the stages thereafter, I'm going to simply enhance the relevance factor:
  • Soundex: Built-in function to list matches that sound like the search term.
  • Levenshtein: Allows for typos and matches to words that are 1 or 2 letters mistyped.
  • Grammar: Account for singular/plural, past/present, and noun/adjective/verb forms.
  • Referencing: If this is a search system for a technical database, and there is one specific article you visit a lot, it would be nicer just to type a number like "1234" and this returns that specific article. In the case of Joomla, we'll use the article ID.

Pre-Notes:
This article consists of instructions to hard-code some core files in Joomla. As a precaution, you may want to back up all your website files and its database. Or, if space is limited, you can backup the files I have listed here (the ones we will be modifying):
  1. \plugins\search\content\content.php
  2. \components\com_search\views\search\tmpl\default.xml
  3. \components\com_search\views\search\view.html.php
  4. \language\en-GB\en-GB.com_search.ini
  5. [IfExists] \modules\mod_rokajaxsearch\mod_rokajaxsearch.xml

Stage 1: Add Relevance [Mandatory Stage]
We want to order by more than just popularity and/or date, but also by our own relevance heuristics. The following change would give radically high relevance to articles where the search term is found in the title.
  1. \plugins\search\content\content.php: Insert this between the if ($sContent && $limit > 0){ and before the from part of the query $query->from('#__content AS a');

    1.  // Add "Relevance" column 
    2.  // + 1000 pts if in title x1 (eg. if word is twice then 2000pts) 
    3.  // + 60 pts if in introtext 
    4.  // + 40 pts if in fulltext 
    5.   
    6.  $sql_keyword = strtolower(trim($db->Quote($db->escape($text, true), false))); 
    7.  $query->select(
    8.       (1000*((LENGTH(TRIM(a.title)) - LENGTH(REPLACE(LOWER(TRIM(a.title)), '.$sql_keyword.',\'\'))) / LENGTH('.$sql_keyword.'))) + 
    9.       (60*((LENGTH(TRIM(a.introtext)) - LENGTH(REPLACE(LOWER(TRIM(a.introtext)), '.$sql_keyword.',\'\'))) / LENGTH('.$sql_keyword.'))) + 
    10.       (40*((LENGTH(TRIM(a.`fulltext`)) - LENGTH(REPLACE(LOWER(TRIM(a.`fulltext`)), '.$sql_keyword.',\'\'))) / LENGTH('.$sql_keyword.'))) AS relevance 
    11.  '); 
    « Show Me »

  2. [Same file again] \plugins\search\content\content.php: Insert this between the if ($sArchived && $limit > 0){ and before the from part of the query $query->from('#__content AS a');

    1.  $sql_keyword = strtolower(trim($db->Quote($db->escape($text, true), false))); 
    2.  $query->select(
    3.       (1000*((LENGTH(TRIM(a.title)) - LENGTH(REPLACE(LOWER(TRIM(a.title)), '.$sql_keyword.',\'\'))) / LENGTH('.$sql_keyword.'))) + 
    4.       (60*((LENGTH(TRIM(a.introtext)) - LENGTH(REPLACE(LOWER(TRIM(a.introtext)), '.$sql_keyword.',\'\'))) / LENGTH('.$sql_keyword.'))) + 
    5.       (40*((LENGTH(TRIM(a.`fulltext`)) - LENGTH(REPLACE(LOWER(TRIM(a.`fulltext`)), '.$sql_keyword.',\'\'))) / LENGTH('.$sql_keyword.'))) AS relevance 
    6.  '); 
    « Show Me »

  3. [Same file again] \plugins\search\content\content.php: Add the option to select by relevance to the CASE order statement:

    1.  $morder = ''; 
    2.  switch ($ordering) { 
    3.   
    4.       // BEGIN: joes new ordering option 
    5.         case 'relevance'
    6.            $order = 'relevance DESC'
    7.            break; 
    8.       // END: joes new ordering option 
    9.        
    10.       case 'oldest'
    11.            $order = 'a.created ASC'
    12.            break; 
    13.   
    14.       case 'popular'
    15.            $order = 'a.hits DESC'
    16.            break; 
    17.   
    18.       case 'alpha'
    19.            $order = 'a.title ASC'
    20.            break; 
    21.   
    22.       case 'category'
    23.            $order = 'c.title ASC, a.title ASC'
    24.            $morder = 'a.title ASC'
    25.            break; 
    26.   
    27.       case 'newest'
    28.       default: 
    29.            $order = 'a.created DESC'
    30.            break; 
    « Show Me »

  4. To add it to the frontend as option in advanced search: OPTION FOR SITE VISITORS \components\com_search\views\search\tmpl\default.xml:

    1.  <field  
    2.                  name="ordering"  
    3.                  type="list" 
    4.                  default="0" 
    5.                  description="COM_SEARCH_ORDERING_DESC" 
    6.                  label="COM_SEARCH_ORDERING_LABEL" 
    7.          > 
    8.                  <option value="newest">COM_SEARCH_NEWEST_FIRST</option> 
    9.                  <option value="oldest">COM_SEARCH_OLDEST_FIRST</option> 
    10.                  <option value="popular">COM_SEARCH_MOST_POPULAR</option> 
    11.                  <option value="alpha">COM_SEARCH_ALPHABETICAL</option> 
    12.                  <option value="category">JCATEGORY</option> 
    13.                    <option value="relevance">COM_SEARCH_MOST_RELEVANT</option> 
    14.          </field> 
    « Show Me »

  5. To add it to the frontend as option in advanced search: FUNCTIONALITY \components\com_search\views\search\view.html.php:

    1.  // built select lists 
    2.  $orders = array(); 
    3.  $orders[] = JHtml::_('select.option',  'newest', JText::_('COM_SEARCH_NEWEST_FIRST')); 
    4.  $orders[] = JHtml::_('select.option',  'oldest', JText::_('COM_SEARCH_OLDEST_FIRST')); 
    5.  $orders[] = JHtml::_('select.option',  'popular', JText::_('COM_SEARCH_MOST_POPULAR')); 
    6.  $orders[] = JHtml::_('select.option',  'alpha', JText::_('COM_SEARCH_ALPHABETICAL')); 
    7.  $orders[] = JHtml::_('select.option',  'category', JText::_('JCATEGORY')); 
    8.    $orders[] = JHtml::_('select.option',  'relevance', JText::_('COM_SEARCH_MOST_RELEVANT')); 
    « Show Me »

  6. To add it to the frontend as option in advanced search: LANGUAGE FILE \language\en-GB\en-GB.com_search.ini:

    1.  COM_SEARCH_MOST_POPULAR="Most Popular" 
    2.    COM_SEARCH_MOST_RELEVANT="Most Relevant" 
    3.  COM_SEARCH_NEWEST_FIRST="Newest First" 
    4.  COM_SEARCH_OLDEST_FIRST="Oldest First" 
    « Show Me »


Third-party AJAX Search modules?
  1. To add it to ROKAJAXSEARCH: \modules\mod_rokajaxsearch\mod_rokajaxsearch.xml:

    1.  <field name="ordering" type="list" default="newest" label="Ordering"> 
    2.       <option value="alpha">Alphabetical</option> 
    3.       <option value="category">Section/Category</option> 
    4.       <option value="newest">Newest first</option> 
    5.       <option value="oldest">Oldest first</option> 
    6.       <option value="popular">Most popular</option> 
    7.       <option value="relevance">Most relevant</option> 
    8.  </field> 
    « Show Me »

    Don't forget to change the setting in Joomla Admin Panel > Module Manager > RokAjaxSearch > Basic Options > Advanced Search > Ordering (no functionality to add if you followed Stage 1 above)


Stage 2: More than Title relevance
So I could stop here as Stage 1 substantially improves your Joomla search, but I'm an anal analyst as well as a programmer and want everything to work perfectly like 1,2,3...

... ok still to come as I'm really happy with what the above already improves!

Comments   

pankaj
# pankaj Tue, 3rd September 2013
what to do for titel name search? done all the changes according to u .but the the no sultion for the titel search. if the the article is new it will shown.but if it is old date article then the result is shown in differnt article body in there content. :cry: :cry:
Like | Dislike | 0 Reply | Reply with quote | Quote
Add Comment

Name:

Email:

Website:

Message:


Latest Posts

  • 301 Redirect using htaccess file

    • Tue 15-Apr-14
      Further suggestion:
      RewriteRule ^(.*/)?assets/s 2dmain.html\?/( .*/)? $2 [R=301,L]
      Webmaster  
    • Thu 10-Apr-14
      Playing with some RegEx testers
      RewriteRule ^(.*\?/)?(?:$|( .+?)(?:(\.[^.]$ )|$)) $2 [R=301,L] ...
      Webmaster  
    • Wed 09-Apr-14
      I tried to redirect links from my old site to my new site, based on what I read in this thread. The old ...
      pelle
  • JComments 2.3.0 with ReCaptcha in Joomla 2.5.x

    • Fri 28-Mar-14
      You are a rockstar mate! thanks. Followed the steps listed and it worked! If only all tutorials were ...
      Kman
  • K2 Items disappear

    • Thu 03-Apr-14
      The fix works great, but the problem is occurring a couple of times a day. Any idea how to fix ...
      Larry C.