2

FAQのリストのためにいくつかの非常に単純な検索機能を書いています。スペースを含むさまざまな文字で検索文字列を分割しています。次に、の線に沿って選択を実行します

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一致の数をカウントし、それによって順序付けて、キーワードが最も多い質問が結果の上部に表示されるようにする方法があるかどうかを誰かが知っていますか?

4

2 に答える 2

3

クエリを実行する直前に、一致するキーワードのリストがユーザーによって入力され、アプリケーションによって動的にクエリに挿入されていると仮定します。その場合は、次のようにクエリを修正することをお勧めします。

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;

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

1 つの注意点: クエリが動的に構築されている場合、SQL 挿入 攻撃のリスクを認識していますか?

于 2011-12-16T13:13:16.323 に答える
2

次のように、ある文字列が別の文字列に出現する回数をカウントする関数を作成できます。

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

そしてそれを選択で使用します:select CountInString("Question",' what ') from "faq".

于 2011-12-16T11:42:31.557 に答える