2011-12-16 6 views
2

私はよくある質問のリストのための非常に簡単な検索機能を書いています。私は、スペースを含む様々な文字に検索文字列を分割しています。そして、その私たちのデータアクセス層によって生成され、わずかにこれを編集するために、私が持っていたCountとWhere By Where句が一致します

SELECT * 
FROM "faq" 
WHERE 
    ((LOWER("Question") LIKE '%what%' 
    OR LOWER("Question") LIKE '%is%' 
    OR LOWER("Question") LIKE '%a%' 
    OR LOWER("Question") LIKE '%duck%')) 

の線に沿って選択を実行するが、それはあなたに起こっていただきました!のアイデアを与える必要があります。

問題は、ほとんどの質問にaまたはその中の単語が含まれている可能性が高いという点で上のクエリでよく説明されていますが、頭字語が検索者にとって重要であるため、これらをフィルタリングできません。提案されているのは、一致するキーワードの数で並べ替えることです。しかし、私はSQLでこれを行う方法を見つけることができませんでした(私たちはキーワードなどのインデックスを持つ簡単な検索エンジンを作成する時間がありません)。 SQLステートメントでLIKEの一致の数を数え、それによって並べ替える方法があれば誰でも知っているので、ほとんどのキーワードを含む質問が結果の上部に表示されます。

答えて

3

CREATE OR REPLACE FUNCTION CountInString(text,text) 
RETURNS integer AS $$ 
SELECT(Length($1) - Length(REPLACE($1, $2, '')))/Length($2) ; 
$$ LANGUAGE SQL IMMUTABLE; 

そして選択でそれを使用しますクエリが実行される直前に、アプリケーションによって動的にクエリに挿入されます。もしそうなら、私はそうのようなクエリを改正提案:

SELECT * 
FROM "faq" 
WHERE 
    ((LOWER("Question") LIKE '%what%' 
    OR LOWER("Question") LIKE '%is%' 
    OR LOWER("Question") LIKE '%a%' 
    OR LOWER("Question") LIKE '%duck%')) 
order by 
    case when LOWER("Question") LIKE '%what%' then 1 else 0 end + 
    case when LOWER("Question") LIKE '%is%' then 1 else 0 end + 
    case when LOWER("Question") LIKE '%a%' then 1 else 0 end + 
    case when LOWER("Question") LIKE '%duck%' then 1 else 0 end 
descending; 

これもユーザー(またはアルゴリズム)を想定し、「体重」の各選択期間の重要性にあなたを可能にする各用語に重み付けを割り当てることができます。

注意:クエリが動的に構築されている場合は、SQL Insertionattacksのリスクに気付いていますか?

+0

ありがとうございましたPgAdminで完璧に動作するようです。私たちは、私たちのためにデータを浄化するEntityspacesというデータアクセス層を使用します。しかし、私たちはこのクエリを自分で構築する必要があるかもしれませんので、注意深く進めてください:) – ClearCarbon

+0

は、私がpgAdminでdesc降順に変更して動作させなければならないことに注意してください。 – ClearCarbon

2

あなたはこのように他に1つの文字列の出現をカウント機能書き込むことができます。私は、一致キーワードのリストが入っていると仮定しselect CountInString("Question",' what ') from "faq".

+0

私はこのことも同様にうまくいくとは確信していますが、ケースバイケースのソリューションは現時点で私たちの状況にとってより適切です。 – ClearCarbon