我正在尝试为基于库存的网站创建搜索引擎。问题是我在 bbtags 中有信息(如 [b]test[/b] 句子
,test
的值应为 3
,而 sentence
的值应为 1
)。
这是一个索引的例子:
My test sentence, my my
(有TST-DFS
的SKU)
数据库:
|Product| word |relevancy|
| 1 | my | 3 |
| 1 | test | 1 |
| 1 |sentence| 1 |
| 1 | TST-DFS| 10 |
但是,如果用户输入 TST DFS
,我将如何匹配 TST-DFS
?我希望该 SKU 具有 8
的相关性,而不是完整的 10
..
我听说 MySQL 中的 FULL TEXT 搜索功能会有所帮助,但我似乎找不到一个好的方法来做这件事。我想避免使用 UNIONS 之类的东西,并尽可能优化查询。
如果能为此想出一个好的系统提供任何帮助,那就太好了。
谢谢, 最大
最佳答案
But how would I match TST-DFS if the user typed in TST DFS?
I would like that SKU to have a relevancy of say 8, instead of the full 10..
如果我答对了,其实答案很简单。
好吧,如果您在将查询发送到 mysql 之前伪造您的查询。
好吧,假设我们有 $query
,它包含 TST-DFS
。
我们要关注单词跨度吗? 我想我们应该像大多数搜索引擎一样,所以:
$ok=preg_match_all('#\w+#',$query,$m);
现在 如果该模式匹配... $m[0]
包含 list of words in $query
.
这可以根据您的 SKU 进行微调,但是以 AND 方式匹配完整单词几乎是用户认为正在发生的事情。 (因为它发生在谷歌和雅虎)
然后我们需要制作一个 $expr
表达式,将其注入(inject)到我们的最终查询中。
if(!$ok) { // the search string is non-alphanumeric
$expr="false";
} else { // the search contains words that are no in $m[0]
$expr='';
foreach($m[0] as $word) {
if($expr)
$expr.=" AND "; // put an AND inbetween "LIKE" subexpressions
$s_word=addslashes($word); // I put a s_ to remind me the variable
// is safe to include in a SQL statement, that's me
$expr.="word LIKE '%$s_word%'";
}
}
现在 $expr
应该看起来像 "words LIKE '%TST%' AND words LIKE '%DFS%'"
有了这个值,我们可以构建最终的查询:
$s_expr="($expr)";
$s_query=addslashes($query);
$s_fullquery=
"SELECT (Product,word,if((word LIKE '$s_query'),relevancy,relevancy-2) as relevancy) ".
"FROM some_index ".
"WHERE word LIKE '$s_query' OR $s_expr";
“TST-DFS”应为:
SELECT (Product,word,if((word LIKE 'TST-DFS'),relevancy,relevancy-2) as relevancy)
FROM some_index
WHERE word LIKE 'TST-DFS' OR (word LIKE '%TST%' AND word LIKE '%DFS%')
如您所见,在第一行 SELECT
中,如果匹配是部分匹配,mysql 将返回 relevancy-2
第三个,WHERE
子句,如果全匹配失败,$s_expr
,部分匹配查询我们提前煮熟,改为尝试。
关于PHP mysql 搜索查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7224931/