2

我正在为常见问题解答列表编写一些非常简单的搜索功能。我将搜索字符串拆分为各种字符,包括空格。然后沿线执行选择

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

我不得不稍微编辑它,因为它是由我们的数据访问层生成的,但它应该让您了解发生了什么。

上面的查询很好地证明了这个问题,因为大多数问题可能包含单词 a 或 is 在其中,但是我无法过滤掉这些,因为首字母缩略词可能对搜索者很重要。建议我们按匹配关键字的数量排序。但是我一直无法在 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;

假设用户(或算法)可以为每个术语分配权重,这甚至可以让您“加权”每个选择术语的重要性。

一个警告:如果您的查询是动态构建的,您是否意识到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 回答