各位亲,多关键词搜索时,存储过程怎么写好?

我正在写一个信息检索程序,PHP+MYSQL,数据库是这么设计的(为简化省去和问题无关的列):
词表T: id, term;其中term列表示关键词,做了唯一索引;
数据样例:[1,'云计算'],[2,'大数据']
文档表D:id, length;其中length列表示文档长度,用于计算排名以便排序搜索结果;
数据样例:[1,300],[2,500]
关系表C:tid,did,count; 表示哪个词出现在哪个文档多少次?前两列是外键,count列也用于计算排名;
数据样例:[1,1,3],[1,2,5],[2,2,10]

对文档集编制索引,也就是向这三个表插入数据,这一步已经完成。

接下来处理查询,用户输入的是自然语言,例如“今年云计算和大数据发展趋势”。
我用PHP提取出关键词“云计算”“大数据”,现在是两个,然后调用存储过程来快速检索:
CALL SP2('云计算','大数据');
存储过程会返回文档id数组,并根据相关度排序,相关度的计算比较复杂,会用到D.length和C.count,以及一些统计数据,比如文档总共有多少个?其中包含词'云计算'的文档有多少个?……

我的问题是,目前我写了SP(K),SP2(K1,K2);可PHP提取出来的关键词数量可以任意多,总不能为每种数量编写一个存储过程吧?请问如何编写一个存储过程,能高效的处理任意多个关键词呢?

我先简要展示一下SP2的伪代码(可能有语法错误,您凑付看,明白意思就好):

-- 计算文档总数,包含关键词K1、K2的文档数
select count(*) into TotalD from D;

select count(*) into TotalDK1 from D
join C on C.did = D.id
join T on C.tid = T.id
where T.term = K1;

select count(*) into TotalDK2 from D
join C on C.did = D.id
join T on C.tid = T.id
where T.term = K2;

-- 检索文档,根据相关度排名,返回给PHP
select D.id, 计算相关度(TotalD, TotalDK1, TotalDK2, length, count) AS rel
from
(
select D.id, D.length, C.count from D join ... where T.term = K1
union all
select D.id, D.length, C.count from D join ... where T.term = K2
)
group by D.id
order by rel desc;

大致如此,您明白了吧,如果再写SP3、SP4、……要了命了!

谢谢!

阅读 1.9k
1 个回答

为啥用数据库实现,用全文搜索啊,一般都有权重功能的...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题