Welcome to Geeklog, Anonymous Monday, November 25 2024 @ 02:50 pm EST

Geeklog Forums

Add 'Search for all words' function to search.php


Status: offline

griffman

Forum User
Junior
Registered: 04/23/02
Posts: 28
I've long been frustrated by the manner in which GL searches are performed. If you search here (gl.sf.net) on "path, geeklog, install" or "path geeklog install", you'll get zero matches (even though all those words appear in this article). This is because GL matches the entire string, not words within the string. While this is occasionally useful, most of the time I'm interested in finding any articles that contain all of the words I'm searching on, not the entire phrase.

Last night, I modified search.php to provide exactly that functionality. I modified both the stories/comments search and the links search ... but if you use events, you'll have to create a similar modification for that section (it's commented out on my site).

I managed to do this while not losing the existing functionality (except in one minor case). If you enter a search phrase in the usual way, GL will search on the phrase. But if you enter it with commas between terms, GL will now find all articles that contain each word (or phrase) between commas in the search line. The "minor case" that I've lost is the ability to search for a phrase that contains a comma, but I believe that to be a very very rare need. This hack will, however, successfully find words and phrases; a search on "geeklog, help with installation, path" will work as expected.The modifications are relatively easy and need to be made in two places (three if you want to modify the events search as well). First, in function searchlinks, look for this bit:
Text Formatted Code
...
if (($type == 'links') || (($type == 'all') && empty ($author))) {
    $sql = "SELECT lid,title,url,hits,group_id,owner_id,perm_owner,perm_group,perm_members,perm_anon,UNIX_TIMESTAMP(date) as day FROM {$_TABLES['links']} WHERE ";
    $sql .= " (title like '%$query%' ";
    $sql .= " OR description like '%$query%')
    ...";


All you need to do is change it to look like this:

Text Formatted Code
...
if (($type == 'links') || (($type == 'all') && empty ($author))) {
    $sql = "SELECT lid,title,url,hits,group_id,owner_id,perm_owner,perm_group,perm_members,perm_anon,UNIX_TIMESTAMP(date) as day FROM {$_TABLES['links']} WHERE ";
    if (substr_count($query,",") == 0) { // no commas, so no WORD searches
        $sql .= " (title like '%$query%' ";
        $sql .= " OR description like '%$query%') ";
    } else {
        $mywords = explode(",",$query);
        $tmp = "";
        foreach ($mywords as $mysearchterm) {
            $tmp .= "(title like '%" . trim($mysearchterm) . "%' OR ";
            $tmp .= "description like '%" . trim($mysearchterm) . "%') AND";
        }
        $tmp = substr($tmp,0,strlen($tmp)-4);
        $sql .= $tmp;
    }
    ...


Next, a similar change in function searchstories. The original looks like:

Text Formatted Code
...
$sql = "SELECT sid,title,hits,uid,group_id,owner_id,perm_owner,perm_group,perm_members,perm_anon,UNIX_TIMESTAMP(date) as day,'story' as type FROM {$_TABLES['stories']} WHERE (draft_flag = 0) AND (date <= NOW()) ";
if (!empty ($query)) {
    $sql .= "AND (introtext like '%$query%'  ";
    $sql .= "OR bodytext like '%$query%' ";
    $sql .= "OR title like '%$query%')  ";
}
...


Change the above section to look like this:

Text Formatted Code
...
$sql = "SELECT sid,title,hits,uid,group_id,owner_id,perm_owner,perm_group,perm_members,perm_anon,UNIX_TIMESTAMP(date) as day,'story' as type FROM {$_TABLES['stories']} WHERE (draft_flag = 0) AND (date <= NOW()) ";
if (!empty ($query)) {
    if (substr_count($query,",") == 0) { // no commas, so no WORD searches
        $sql .= "AND (introtext like '%$query%'  ";
        $sql .= "OR bodytext like '%$query%' ";
        $sql .= "OR title like '%$query%')  "
    } else { // need to do WORD searches
        $mywords = explode(",",$query);
        $sql .= "AND ";
        $tmp = "";
        foreach ($mywords as $mysearchterm) {
            $tmp .= "(introtext like '%" . trim($mysearchterm) . "%' OR ";
            $tmp .= "bodytext like '%" . trim($mysearchterm) . "%' OR ";
            $tmp .= "introtext like '%" . trim($mysearchterm) . "%') AND ";
        }
        $tmp = substr($tmp,0,strlen($tmp)-4);
        $sql .= $tmp;
    }
}

That's it! You should now be able to search on both phrases (words without commas) and multiple instances of words (separate them with commas). This hack has already saved me a bunch of time in finding previously published material. While not as cool as a full-blown logical search engine with 'and' and 'or' capabilities, it was much simpler to write!

I don't guarantee that this is the most efficient code, so improvements (and any potential traps you see) are welcomed...
 Quote

Status: offline

akerin

Forum User
Junior
Registered: 08/22/02
Posts: 19
The search function on geeklog.sf has always frustrated me. Hopefully this will be incorporated into the site. Good work
 Quote

Status: offline

griffman

Forum User
Junior
Registered: 04/23/02
Posts: 28
In the last code snippet, I wrote:
Text Formatted Code
foreach ($mywords as $mysearchterm) {
            $tmp .= "(introtext like '%" . trim($mysearchterm) . "%' OR ";
            $tmp .= "bodytext like '%" . trim($mysearchterm) . "%' OR ";
            $tmp .= "introtext like '%" . trim($mysearchterm) . "%') AND ";
The last line needs to have introtext replaced with title. Sigh; almost got it all right! ;-) -rob.
 Quote

Status: offline

rv8

Forum User
Regular Poster
Registered: 10/10/02
Posts: 105
Location:Ottawa, Canada

Has anyone got this to work? If so, I would love to get a copy of your search.php file. I tried it on my local server, but now I get:

Parse error: parse error, unexpected '}' in /Library/WebServer/Documents/search.php on line 276

I don't know enough php to figure out what is wrong.

Thanks,

Kevin


Kevin Horton
 Quote

Status: offline

rv8

Forum User
Regular Poster
Registered: 10/10/02
Posts: 105
Location:Ottawa, Canada

Well, I did a bunch of experimenting, and it looks like there are two additional problems with the code to be inserted in function searchstories.

First, there needs to be a semicolon at the end of the third $sql line. It should look like:

$sql .= "OR title like '%$query%') ";

Second, the last } must be removed, at the very end of the code to be inserted.

I made these changes and everything seems to work correctly now. I also went into the english.php file and changed the line that comes up in the Advanced Search dialog to explain the new functionality.

Kevin


Kevin Horton
 Quote

Anonymous

Anonymous
Hi! Thats function is great! Can you add an URL so we can download the modified file? Cheers, Rune!
 Quote

Status: offline

muskrat

Forum User
Chatty
Registered: 10/31/02
Posts: 41
Thanks for figuring this out. I managed to modify the search function for the staticpages plugin v1.2 so it works with multiple, comma-separated terms also. I'm stumped by the external pages plugin though. I can't see how it builds the query for the search. Has anyone gotten this type of search to work with the external pages plugin? My site uses external pages and static pages a lot so I hope I can get this working.
 Quote

All times are EST. The time is now 02:50 pm.

  • Normal Topic
  • Sticky Topic
  • Locked Topic
  • New Post
  • Sticky Topic W/ New Post
  • Locked Topic W/ New Post
  •  View Anonymous Posts
  •  Able to post
  •  Filtered HTML Allowed
  •  Censored Content