我开发了一个带有搜索框的网站,当有人搜索任何单词(例如"car")时,我在数据库上运行一个查询,检查搜索的单词是否包含在关键字表中。我的意思是,如果关键字表中有"汽车",我就会在网站上返回与该关键字相关的内容。
数据库有2个表用于搜索:内容表(id_content,名称,描述,别名,…)和关键词表(id_keyword, keyword, id_content),这意味着每个内容有N个关键词,1个名称,1个描述和1个别名。
但是现在我想通过检查搜索是否不仅匹配关键字,而且匹配名称、别名和描述来更好地重新定义搜索。唯一的问题是,我不知道如何做到这一点,因为有些内容将只有一个匹配的关键字,其他将有匹配的名称和关键字(只是一个例子),有些将实际上有一个匹配的名称,描述,别名和关键字。
我的目标是让我的搜索首先检索完整匹配的(名称,描述,别名和关键字),然后是3匹配的,然后是2匹配,最后,只有1匹配的(尽管匹配是名称,描述,别名或关键字)。
我不确定我是否讲得足够清楚,请随时询问细节。
谢谢。
编辑1
通过关键字获取对象的函数:
public function get_object_id_by_keyword($keyword, $limit = 3){
$id = "";
$sql = "SELECT id_object FROM addons_keywords WHERE keyword = '".$keyword."' limit " . $limit;
$res = $this->db->query($sql);
if($res->num_rows() == 1){
$id = $res->row(0)->id_object;
}
else{
$id = array();
for($i=0; $i<$res->num_rows(); $i++){
array_push($id, $res->row($i)->id_object);
}
}
return $id;
}
SQL Code获取"full match":
SELECT id_object
FROM addons_keywords
WHERE keyword = 'searched'
UNION
SELECT id_object
FROM objects
WHERE name LIKE '%searched%'
AND description LIKE '%searched%'
AND alias LIKE '%searched%'
从这里,我能做的是查询完整的匹配,如果没有足够的内容(内容=对象和$limit是我需要的结果的数量),我将做查询旁边的"完整匹配",这将是一个"3匹配"。我的问题是,3匹配可以是名称+描述+别名,名称+别名+关键字,描述+别名+关键字,等等…
编辑2
SQL代码为"1匹配"(不确定联合是否正确):
SELECT id_object
FROM addons_keywords
WHERE keyword = 'searched'
UNION
SELECT id_object
FROM objects
WHERE name LIKE '%searched%'
OR description LIKE '%searched%'
OR alias LIKE '%searched%'
3
编辑
刚刚意识到"完全匹配"SQL是不正确的,因为它将返回没有搜索描述的对象的id_object(刚刚测试了它)。也许联合工会不是正确的选择…是吗?
也许这行得通?
SELECT
id_object,
(name LIKE '%searched%')
+ (description LIKE '%searched%')
+ (alias LIKE '%searched%')
AS score
FROM objects
WHERE id_object IN (
SELECT id_object
FROM addons_keywords
WHERE keyword = 'searched'
)
HAVING score > 0 -- remove this to allow keyword-only matches
ORDER BY score DESC
如果关键字不是强制性的,只需删除WHERE
并将关键字添加到相关计数器:
SELECT
id_object,
(name LIKE '%searched%')
+ (description LIKE '%searched%')
+ (alias LIKE '%searched%')
+ (id_object IN (
SELECT id_object
FROM addons_keywords
WHERE keyword = 'searched'
)
)
AS score
FROM objects
ORDER BY score DESC
请注意,这个查询不是特别有效。如果您的数据集非常大,那么您最好使用Sphinx或Solr等专用全文引擎。