views:

58

answers:

3

I've been asked to put together a search for one of our databases.

The criteria is the user types into a search box, SQL then needs to split up all the words in the search and search for each of them across multiple fields (Probably 2 or 3), it then needs to weight the results for example the result where all the words appear will be the top result and if only 1 word appears it will be weighted lower.

For example if you search for "This is a demo post"

The results would be ranked like this

Rank   Field1                 Field2
1:     "This is a demo post"  ""
2:     "demo post"            ""
3:     "demo"                 "post"
4:     "post"                 ""

Hope that makes some sort of sense, its kind of a base Google like search.

Anyway I can think of doing this is very messy.

Any suggestions would be great.

A: 

Logically you can do this reasonably easily, although it may get hard to optimise - especially if someone uses a particularly long phrase.

Here's a basic example based on a table I have to hand...

SELECT TOP 100 Score, Forename FROM
(
    SELECT
     CASE
      WHEN Forename LIKE '%Kerry James%' THEN 100
      WHEN Forename LIKE '%Kerry%' AND Forename LIKE '%James%' THEN 75
      WHEN Forename LIKE '%Kerry%' THEN 50
      WHEN Forename LIKE '%James%' THEN 50
     END AS Score,
     Forename
    FROM
     tblPerson
) [Query]
WHERE
    Score > 0
ORDER BY
    Score DESC

In this example, I'm saying that an exact match is worth 100, a match with both terms (but not together) is worth 75 and a match of a single word is worth 50. You can make this as complicated as you wish and even include SOUNDEX matches too - but this is a simple example to point you in the right direction.

Sohnee
A: 

"Google-like search" means: fulltext search. Check it out!

With SQL Server 2008, it's totally integrated into the SQL Server engine.

Before that, it was a bit of a quirky add-on. Another good reason to upgrade to SQL Server 2008! (and the SP1 is out already, too!)

Marc

marc_s
A: 

I ended up creating a full text index on the table and joining my search results to FREETEXTTABLE, allowing me to see the ranked value of each result

The SQL ended up looking something like this

SELECT
    Msgs.RecordId,
    Msgs.Title,
    Msgs.Body
FROM
    [Messages] AS Msgs
    INNER JOIN FREETEXTTABLE([Messages],Title,@SearchText) AS TitleRanks ON Msgs.RecordId = TitleRanks.[Key]  
ORDER BY
    TitleRanks.[Key] DESC

I've used full text indexes in the past but never realised you could use FullTextTable like that, was very impressed with how easy it was to code and how well it works.

Gavin Draper
You may want to consider ordering by TitleRanks.Rank, which is the implicit column (ranges from 0-100) to indicate how well each row matched the search criteria.
JonoW
Sorry should have been TitleRanks.Rank DESC (100 is most relevant, 0 least)
JonoW