转自:http://wubin850219.iteye.com/blog/516418
/**
*
*作者:野四abin
* 时间:2009-3-27
*/
搜索引擎现在越来越流行了,好多网站都有了自己的搜索引擎,但是对于类似GOOGLE的提示并不多,在我的印象中并没有太多(google,baidu.todou,youku…),而大多数都是一些比较大型的网站在使用这个功能.由于公司的搜索引擎的需求要求实现关于类似google提示功能!
如下图
通过浏览别人做的搜索引擎提示总结出来我所面临的问题如下:
1、提示中的那些关键字是如何获得的
2、提示中的关于那些关键字的搜索数据条数如何获得的
3、关于得到这些数据的访问速度
通过上述问题我总结出来了关于这些问题的实现方案
对于第1个问题,我认为应当是用户通过搜索引擎搜索使用关键字的记录的。我是如果得到这些记录和如何存储这些记录的呢!
首先我新建一个表(关键字搜索记录表)主要是存储使用关键字搜索记录,它包括以下几个字段(ID,关键字,使用次数) 其中关键字是唯一的!我是怎样存储这些数据的呢!首先我创建一个searchkeys.txt文本文件,每个搜索使用的关键字写入文本中,每个关键字点一行,我是通过定时器来把这个数据存储到数据库当中的,通过分析这些数据如果有N个相同的关键字使用次数就为N个,我是每天0点的时候把这些数据存储在数据库中,为什么要选择0点,因为0点的时候访问量并不会太多,加入数据库中也不会影响网站的速度。同时能过分析数据中的记录生成一个名叫searchkeys.js的文件,它的格式如下:
- var keyArr1=new Array();
- keyArr1[0]=["1","办公摆挂件","1000"]
- keyArr1[1]=["2","办公剪刀","1000"]
- keyArr1[2]=["3","办公沙发","1000"]
- keyArr1[3]=["4","办公饰品","1000"]
- function getArr1(skey){
- function funsort(x,y){//通过使用次数来排序
- return y[1] - x[1];
- }
- var j=0;
- var testArray = new Array();
- var keyArray = new Array();
- for (var i = 0; i < keyArr1.length; i++) {
- if (keyArr1[i][1].indexOf(skey)==0) {//根据字来查找
- testArray[j]= new Array(keyArr1[i][1],keyArr1[i][2]);
- j++;
- }
- }
- testArray.sort(funsort);
- for (var sk = 0; sk < testArray.length; sk++) {
- if(sk<10){//只取前10条结果
- keyArray[sk]= new Array(testArray[sk][0],testArray[sk][1]);
- }else{
- break;
- }
- }
- return keyArray;
- }
为什么要使用这个JS呢?减少与数据库连接,
那关键词后面的结果条数怎么得来的呢,我认为是通过对关键词的的分词,再通过这个关键词分词后的各个分词,去索引中查找关于这些关键字的HITS的记录,这里我只得到这些个数,并通过使用memcached来存储这个使用关键字与得到的结果个数!
测试结果:
输入关键字和出现提示的时间差<0.001s
/**
*
*作者:野四abin
* 时间:2010-4-30
* 补充
*/
对于用JS来存储提醒关键字的做法对于小数量的数据来说应当还行,但是我一直在想如果数据有10M或更多呢?那不是页面加载JS不是更慢,让网站打开的页面更慢了!通过对以上问题的思考,我想到用LUCENE来解决这个问题,首先把前面说到的关键字搜索记录表的数据全部通过建立索引存储到磁盘中,建立索引的过程中值得注意的对于你的提醒关键字不能做分词,只能做不分词索引;再通过PrefixQuery对搜索的提醒关键字查找,为什么提醒关键字不能做分词索引呢?如果做了分词索引则通过PrefixQuery得到你想要的前缀词组的关键字列表,是一个含有这个关键字的分词词组!