java实现站内搜索

   日期:2024-12-26    作者:52g4b 移动:http://ljhr2012.riyuangf.com/mobile/quote/44437.html
1.站内搜索
在以往的网站建设,企业系统的搭建过程中,因为信息比较简单,比较少,站内搜索可能不是必要的选项,而今,时代的发展, 信息量的增大,网站逻辑的复杂,企业自身对信息架构、管理、发布的需求,以及用户对信息的组织、查询、可寻性的要求越来越高,于是站内搜索出现了。
2.和别的搜索引擎的区别
谷歌、百度、搜搜等通用搜索引擎都会免费开放站内搜索功能,以嵌入网页代码的形式保持与搜索引擎机器人的沟通、爬取,其弊病有如下三种
  1、这些通用搜索引擎不能及时、全部抓取网站最新页面内容。这对电子商务网站信息(如价格、活动有效时间等)经常更新的特点来说是致命的,用户查到的可能是过时信息.
  2、既然是所谓通用引擎,其对搜索结果的展示也是通用的,没有差异性的。其不能按照商城自身业务逻辑去做排序、过滤、展示是其最大的弱项
  3.通用搜索,无法提供热词,搜索推荐词,关联词等功能,还需要二次开发,增加工作量复杂度.
  因此,站内搜索的出现也是有其具体原因和需求的,在搜索的精确度和效果上击败了通用搜索引擎。
3.站内搜索的优点
              能够很快的得到用户所要检索的信息,这样给用户提供了很大的方便
4.站内搜索的技术流程
  • 第一步 提取原料:抓取网站页面或格式化数据。
  • 第二步 把原料归类:建立索引,把关键字和页面一一对应上,分类放好(想象一下老式图书馆里的归档管理方法就能形象理解索引了
  • 第三步 听用户要上啥菜:响应用户的搜索需要,对用户输入的关键词进行分解,从索引中找到符合该关键词的所有相关网页。
  • 第四步  摆盘上桌:对搜索结果页面进行排序,将页面标题、url、摘要等信息呈现给用户。
一步步细说
第一步:提取原料:抓取网站页面或格式化数据。
抓取页面是使用一种叫蜘蛛的程序,一个网站中成千上万个页面是通过什么关联起来的?url。蜘蛛就是通过一个页面的url找到另一个页面再找到另一个页面,把所有能链到的页面遍历一边,记录下来。
通用搜索引擎(google baidu)的蜘蛛 很复杂,因为一个页面上可能有很多个url,每个url又关联着无数页面,整个网络像一棵树,假设首页是第一层,首页上的url关联的页面是第二层,第二层页面上url关联的页面是第三层……
蜘蛛抓取的顺序就会很重要,是沿着一个url一直爬下去,还是先爬完一层再爬一层;加密或需要用户登录后才能访问的内容怎么抓取;pdf、rar及多媒体文件怎么抓取,都有讲究。不同的抓取处理在有效性、效率和对 被爬网站的资源占用 上有很大差异。
当然站内搜索没有那么麻烦,一般是技术人员根据希望被纳入搜索的内容数据库 生成一份格式化的 xml文档,让蜘蛛直接抓取就行了。但是站内搜索在提抓取页面更新索引时,有一个指标比较高,那就是抓取的更新频率。
比如对于电商类网站,某些商品,特价、抢货啦,可能刚发布出来5分钟就卖完了,或者改价格了。但是用户听说促销啦,来网站上一搜,搜不到,或者搜到了点进去发现价格不对,用户就会不舒服。 这就是蜘蛛抓取页面的更新频率过低导致的。要解决这个问题并平衡性能与资源占用之间的矛盾,需要多种算法组合优化。
通用搜索 比如google、twitter在做这方面的努力,也就是做成实时搜索。但是站内搜索服务还鲜有尝试者霍炬余晟最近在做针对电商类的优化。目前可以做到即时更新,也就是发布后1分钟内就可以被搜索到。
第二步:把原料归类:建立索引。
建立索引这一步 集中了搜索引擎 的两大核心技术难点:索引结构和中文分词。
如果按照正常人的思维,索引应该是这样建立的
  • 把每篇文章存在文章索引表里(假定我们叫它doc索引,然后解析出该文章中有多少关键字,把关键字存在一个表里(我们叫它keyword索引)
  • doc索引的大致结构就是:docID  | doc标题/内容 | doc的url及其它信息 | doc中每个keywordID 。
  • 当用户输入关键字搜索的时,先找到关键字对应的keywordID, 然后查找到有哪些doc里包含做这个keywordID。
这种思路很符合逻辑,但是不好意思,在效率上几乎是不可行的。
因为在查找哪些doc里包含这个keyword的过程相当于 哗哗哗狂翻一本书来找里面的一个词。网站的doc索引条目动辄上万上十万,要是同时查找多个关键字,相当于多次狂翻一本十几万页的书,你说是不是累死了。
于是 就有一种更符合 程序运行方式的 索引建立方法。这就是倒排索引,也叫反向索引。 而上文中提到的符合正常人思维的叫正排索引。
倒排索引中“倒”的含义是指把doc索引和keyword索引的关联次序颠倒过来。在建立索引的时候,先建一张keyword表,结构是:“keywordID  | 关键字 | 存在哪篇doc中的哪个地方 ”
“存在哪篇doc中的哪个地方” 这个信息怎么表示
通过一种叫映射的方法。通俗地举例:“北京”这个词出现在 id为0011文章的第2段第5行第3个字,可以表达为一个字符串 0010p2l5f3,所以“北京”这个词在keyword表里是可能这样写
“ k001 | 北京 | 0010p2l5f3 , 0010p5l1f9, 0012p1l2f6……”
这是一个平面的结构,实际程序中当然不会这么简单处理,这样效率还是太低。会处理成一个有层次的结构,比如第一层只存docID  “k001 | 北京 | 0010,0010,0012……” ,第二层再存是属于哪一段哪一行等。
这样做的好处是 可以在第一层实现一次归并。因为搜索结果页面最先需要列出的只是那篇文章里包含哪个关键字,不需要具体位置,所以,当北京这个词在0010文章中多次时,第一层索引可以归并为为 “北京| 0010,0012 “ 这样结构又精简了。
索引的结构及存储方法对 搜索速度起致命的影响。
分词: 中文分词技术是中日韩语专属的一个的高难度课题,研究了十几年了。而英文每个单词之间都有空格,没这个麻烦。
比如 “作家长平时常翻阅这本书” 这句话 人可以识别“ 作家 长平 时常 翻阅 这本 书”。但是计算机可能就分成了“ 作 家长 平时 常 翻阅 这本 书”。计算机不认得“长平’ 这个人名,导致分词错误,用户搜索长平的时候就得不到这条结果。
再例如,当用户输入 “和服”搜索时,出来第一屏都是 “产品和服务”,“化妆和服装自己搞定”,用户是不是很郁闷。
所以分词技术 对于 搜索的准确有效性 起关键作用。
基础的分词方法是机械切分,也叫二元切分。以2个字为一个单位进行切分,不进行判断,比如 中华人民共和国 -> 中华 华人 人民 民共 共和 和国
在此基础上进化出了双向最大切分,就是把一句话切成最小词单元,正向切分一次,再反向切分一次,比较下哪个更合理,再通过复杂算法识别出有效关键字。
更先进的方法是在机械切分的基础上使用合理的词库,地名、品牌名、机构、简称等需要词库。而不同行业如金融类、计算机类、商品类都有不同的专业词库。
还有基于人工智能和统计概率的分词算法,但是对于站内搜索这个量级的都不适用。
对于站内搜索而且,除了好的分词算法,更重要的是词库添加和统计功能。网站管理员可以根据用户搜索行为的统计分析 手动向词库内添加新词。
第三步:听用户要上啥菜:响应用户的搜索需要
  • 用户输入的搜索条件可能是一句话,所以对用户搜索请求的解析也要用到分词技术。如果搜 “吉野家沙拉” 和 “吉野家 沙拉” 会得出不一样的搜索结果,就是比较差的搜索引擎了。
  • 用户输入的关键字是对词库的有利补充。比如搜全聚德的人多了,全聚德显然是一个有效的专业词汇。
  • 多个搜索关键字之间存在逻辑运算关系。逻辑运算。。不要怕,搞设计的人应该都知道布尔运算。。不知道?总知道反选、多选、选区交集吧。这就是逻辑运算中 非运算(not)、  或运算(or)、 与运算(and)。
用户的搜索条件是“美国 金融危机”如果采用 或运算,则文章中只要包含了 美国 或 金融危机 这两个词中的一个,都有可能被列为搜索结果。 如果采用 与运算,则只有同时包含了 美国 和金融危机这两个词的文章 采会被列进搜索结果。
所有搜索引擎都应该在输入搜索条件时,支持逻辑运算符。
对于通用搜索引擎,一般 多个关键词之间的空格 就默认代表了是 与运算(and) 的关系。可以通过输入逻辑运算符 来完成其它搜索需求。比如 可以使用 “哈希 or Hash” 来搜索更多关于哈希算法的信息中英文都有, 也可以使用 “小李飞刀—电视剧” (减号)来搜索除电视剧外的小李飞刀的信息。
对于站内搜索,1 没有通用搜索那么大的数据量 2 比搜索引擎专业性更强。所以站内搜索 多个关键字之间的空格 默认代表的是 或运算 的关系。但是会在呈现结果的排序上做文章,通过多种算法计算出相关性最高的文章排在前面,相关性弱的排在后面。这样可以帮助用户发掘到更多 关联性内容,结果呈现也更人性化。这是通常定义下的 站内全文检索 的一个重要特征。也是区别于数据库搜索的技术优势。
响应用户搜索条件的时候 还有字段匹配及权重的问题,一篇doc 可能有标题、摘要、正文、tag、作者等多字段信息存在doc索引库里。Keyword是出现在标题、摘要还是正文中时,权重是不一样的。
第四步 摆盘上桌:对搜索结果页面进行排序
琢磨过SEO的同学一定知道,所谓搜索引擎优化 1是让蜘蛛能抓取自己网站上更多的页面2 让自己网站的页面在搜索结果里能排得更靠前。
这就要研究搜索引擎的排序算法。对于各个通用搜索引擎,排序算法是许多人的关注核心,每次权重调整都会带来巨大震荡。通用搜索引擎都是在基于相关性排序上在加上各自的算法,如Google的专利pagerank就是通过页面之间的互链来判断页面的价值高低,再加上链接引用页面的PR值、是否在一个分类等 各种其它指标。
但是站内搜索,用互链这种方式来判定显然不靠谱,所以主要还是通过优化相关性的算法,计算keyword和DOC之间的关系,例如 keyword 在doc中出现的密度,词频, doc是否和 keyword 属于同一语义类别,doc的长度属性(短的doc应该降权之类的)等判定 keyword的搜索结果中,哪些doc更重要更有价值。
多个关键字的搜索条件,让算法更复杂,如何对多个关键字进行比较、两者的结果如何合并,两者的结果顺序如何穿插重排。
最后还要利用算法来优化 结果排序的速度和稳定性。
由此 才能得到站内搜索的相关度排序结果。
5.站内搜索的实现
首先看下一个数据库的表关系图
在一个网站中可能会有很多的信息类型,若是每个类型板块设定一个数据库表可能会很麻烦。如上图所示,这样设计可以动态的增加板块,并且可以减少数据库的压力
其中数据类型的主键是信息表的外间,这样就形成了一对多的关系,也就是说可能是一个信息类型中包含很多条信息。
若是我们想在网站中查找到自己所需要的信息,例如,查找一级标题,二级标题,或者内容中的关键字来找出文章,我们该如何实现呢
我们首先想到的问题是模糊匹配的原则,这样会有两种方式我们可以解决,一种是通过数据库的方式来实现, 一种是通过java提供的match来显示。
下面是我的通过数据库的方式来实现的, 个人认为这样实现比较直观易懂
我们知道通过like语句,提供模糊查询的操作,如下
select *  from msg where title like '%gjz%' or titlesec like '%gjz%' or contents like '%gjz%'
这样我们可以根据后台传过来的关键字(gjz) 来进行查询,最后将结果返回给用户。
我是用java做的网站,用的是ssh框架,下面我大体介绍下我个人的做法
在daoImpl中写出要查询的方法语句
然后再action中的代码如下
我们是通过页面传过来gjz(关键字)这个变量来确定你查询的条件的
下面我们来看下页面

特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。


举报收藏 0评论 0
0相关评论
相关最新动态
推荐最新动态
点击排行
{
网站首页  |  关于我们  |  联系方式  |  使用协议  |  隐私政策  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  鄂ICP备2020018471号