基于Lucene/XML的站内全文检索解决方案

xml|解决|全文检索

版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
http://www.chedong.com/tech/weblucene.html

内容摘要:
为Lucene做一个通用XML接口一直是我最大的心愿:更方便的在WEB应用中嵌入全文检索功能

提供了XML的数据输入接口:适合将原有基于各种数据库的数据源导入到全文索引中,保证了数据源的平台无关性;
通过了基于XML的搜索结果输出:方便了通过XSLT进行前台的结果显示;
    MySQL  \                                                  / JSP        Oracle - DB      -  ==>   XML ==> (Lucene Index) ==> XML  -  ASP        MSSQL  /                                                  -  PHP                         MS Word /                                        \         / XHTML                 PDF /                                         =XSLT=> -  TEXT                                                                        \ XML                                                                                                     \_________WebLucene__________/ 使用过程如下:
将数据用脚本导出成XML格式;
将XML数据源导入LUCENE索引;
从WEB界面得到XML结果输出,并通过XSLT生成HTML页面

站内全文检索的必要性
虽然大型搜索引擎的功能已经越来越强大了,很多站点都使用了Google的站内检索site:domain.com代替了自己的站内数据库“全文”检索。但依靠GOOGLE这样的大型搜索引擎做站内检索会有以下弊端:

数量有限:搜索引擎并不会深度遍历一个网站,而将网站所有的内容都索引进去,比如Google就喜欢静态网页,而且是最新更新的,而不喜欢带?的动态网页,Google甚至会定期将缺少入口的网站内容逐渐抛弃;
更新慢:搜索引擎针对站点的更新频率也是有一定周期的,很多内容需要一定时间后才能进入GOOGLE的索引:目前Google Dance的周期是21天左右;
内容不精确:搜索引擎需要通过页面内容提取技术将导航条,页头页尾等内容过滤掉,反而不如直接从后台数据库提取数据来得直接,这种摘要和排重机制是很难实现的;
无法控制输出:也许有更多的输出需求,按时间排序,按价格,按点击量,按类目过滤等
系统的搭建
下载:
http://sourceforge.net/projects/weblucene/

XML数据源的导入:

只要数据源可以导出成3层的XML结构,就都可以用IndexRunner这个命令行工具导入:

比如从数据库导出:news_dump.xml
<?xml version="1.0" encoding="GB2312"?>
<Table>
    <Record>
        <Title>标题</Title>
        <Author>作者</Author>
        <Content>内容</Content>
        <PubTime>2003-06-29</PubTime>      
    </Record>
    <Record>
        <Title>My Title</Title>
        <Author>chedong</Author>
        <Content>abc</Content>
        <PubTime>2003-06-30</PubTime>
    </Record>
    ...
</Table>

IndexRunner -i news_dump.xml -o c:\index -t Title,Content -n Author
-i news_dump.xml:  以news_dump.xml为数据源
-o c:\index   索引库建立在c:\index目录下
索引建立Title Author Content PubTime这几个字段外,按以下规则建立索引:
-t Title,Content 一个进行分词的全文索引TokenIndex:数据是Title Content这2个字段
-n Author    一个不分词的索引:NoTokenIndex:数据源是Author这个字段。

对于RSS数据源:
<?xml version="1.0"?>
<rss version="0.92">
<channel>
  <title>Amazon: Books Arts & Photography</title>
  <link>http://www.lockergnome.com/</link>
  <description>Amazon RSS Feed</description>
  <lastBuildDate>Sun, 29 Jun 2003 01:05:01 GMT</lastBuildDate>
  <docs>http://www.lockergnome.com/</docs>
  <webMaster>amazonfeed@lockergnome.com (Lockergnome RSS Generator)</webMaster>
  <item>
    <title>The Artist's Way: A Spiritual Path to Higher Creativity - $11.17</title>
    <link>http://www.amazon.com/exec/obidos/ASIN/1585421464/lockergnomedigit/?ref=nosim&dev-it=D34HUVGKB34YFX</link>
    <description>http://www.lockergnome.com/    </description>
  </item>
  ...
</channel>

IndexRunner -i http://www.example.com/rss.xml -o c:\index -t title,description -n link  -l  4
-l 4 表示拿第4层节点作为字段映射,

IndexRunner还提供了-a -m这两个选项:用于增量索引和批量索引优化。
-a  增量索引,表示在原有索引的基础上扩展
-m  mergeFactor 在Lucene中mergeFactor是一个针对批量索引的优化参数,控制多少条处理完多少条记录(Document)后,写入一次索引,写入频率越高,内存使用越少,但索引速度越慢,所以在大批量数据导入时需要增大文件写入的间隔,多让索引在内存中操作。

搜索结果输出:

以下是系统设计过程中一些设计的思路:

做为工业标准的XML
记得以前有关于肯德基的炸薯条断顿的报道。从这个事件报道中我们可以看到一种更高效的管理体系:对于快餐店这样全球性的企业来说,要保证各地提供的薯条品质,成本最低的方法肯定是依靠机器而不是厨师,如果要求薯条机能够处理各种形状不一的土豆,机器的复杂程度和维护成本都会很高。所以土豆必须严格符合工业标准才能让结构比较简单的薯条机生产出符合标准的薯条,因此,薯条的加工机械会严格按照土豆协会的土豆工业标准设计。高质量的原料可以大大降低后期加工设备的成本,因此从总体成本上讲还是合算的。
对于软件应用开发者来说:应用和应用之间,企业和企业之间交换的数据好比就是土豆,白菜,按照严格的XML标准设计的接口作为企业之间后台数据交换的工业标准,虽然不如简单的CSV格式高效,但缺能大大简化下游工序的后期加工成本。

不难想象为什么处理HTML的浏览器:IE和Mozilla等浏览器软件大小都在10M以上,但一般处理XML的解析器一般都在几百K。除了没有界面外,HTML浏览器需要为太多不规范的HTML代码提供大量容错处理也是一个很重要的原因,而语法严格,规则简单的XML处理器就可以做的很简短,高效,体积越“小”就意味着适应性越广:这点在手机这样的硬件配置比较低的设备环境中显得尤其重要。

虽然XML在后台数据交换方面,有着巨大的潜力。在前台表现方面,XML并不会马上代替HTML,很多通过XSLT输出的HTML仍然需要结合CSS来进行表现。XML ==XSLT==> HTML + CSS。但是由于太多的网页都是用HTML做的,相信XML没有必要马上代替这些已有的机制。

此外在应用的国际化支持方面XML和Java简直是绝配:XML数据源用Java解析后是UNICODE,这样无论是日文,繁体中文还是德文的内容我们都可以在一个索引库中同时进行搜索。这样针对其他语言的支持只是设计各种语言界面的问题了。

      GBK          \                                       / BIG5      BIG5          -  UNICODE        ====>       Unicode -  GB2312      SJIS          -   (XML)                     (XML)   -  SJIS      ISO-8859-1   /                                       \ ISO-8859-1
使用XML的另外一个额外好处在于:开发人员一般都没有仔细理解Java的字符集(其实上是JVM的缺省file.encoding属性)受系统本地化设置的影响,基于XML的输入使得数据的字符解码过程变得透明:不用再和用户解释需要如何解码,编码数据源。不过,XML的学习成本还是比较高的,假设你HTML的学习成本是1,XML则可能为10,而XSLT的学习成本则可能高达100。

传统数据库应用的全文检索加速
让数据库负责精确匹配,将模糊匹配用独立的系统实现
一个站点内容积累在万级以上,站内全文检索就会是用户定位最主要的手段,而关键词检索是用户最熟悉的方法。因此基于数据库的传统WEB应用在全文检索需求还是很大的。

但是可怕的%like%数据库操作可能会吃掉数据库服务器90%以上的CPU。Oracle MSSQL等数据库服务器中数据库内置的全文检索基本上都不太适合WEB应用。而数据库另外一个的弊端在于对于条件简单的查询返回结果集非常大:数据库并不知道如何面向用户最关心的的头100条结果进行优化。根据以前的统计:头100条结果往往已经可以满足95%以上用户需求。

需要缓存设计:根据我们的经验,在应用设计中没有必要进行内置的结果缓存设计:让前台的应用服务器内置的缓存机制或者反相代理缓存服务器进行缓存就够了。

数据同步策略
总体上讲,全文检索和数据库其实是2种根本不同的应用模式,全文检索系统其实往往也没有必要和数据库那么高的实时同步机制,如果按照:低更新,高缓存的模式进行设计:数据库数据到全文索引的同步过程一般都可以通过脚本定期将数据库的数据导出成XML,然后进入Lucene的全文索引。而针对原有数据记录的更新和删除,其实一般可以通过定期的重建索引解决。WebLucene其中索引部分是一个IndexRunner的命令行程序实现的。

结果排序策略
站内全文索引另外一个很重要的需求是可定制的排序:按时间,按价格,按点击量……Lucene全文索引缺省只提供了根据关键词在原文中的匹配度排序,而任何根据某个字段的值进行排序的都无法避免再次遍历数据,从而导致性能有数量级的下降(等于又是做%Like%检索),而在索引中,除了匹配度SCORE外,唯一能用来排序的就是索引记录的ID,所以一个比较高效率实现定制排序的方法时:在索引时,让进入Lucene全文的顺序对应着一定规则:比如时间,然后在搜索时,让搜索结果按照索引记录的ID进行排序(或倒排)。

搜索结果关键词标引的实现
搜索结果中关键词通过红色或者黑体字标记出来,为了能够更恰当的显示相关上下文的问题,标引是通过限制了一个扫描范围,然后根据一个分析器将指定的词流式的读取出来,然后

全文检索和其他应用的集成
其实核心的是一个Lucene的XML接口:SAX方式的数据导入和DOM方式的结果输出。

XML的数据源定义:
只要是能够映射成表=》记录=》字段这样层次结构的都可以。因此WebLucene索引的设计比较灵活,甚至可以直接用来索引RSS。

XML结果定义:参考了Google的XML接口的设计

如果没有SERVLET界面,提供XML输出的DOMSearcher也可以很方便集成到各种应用系统中。

参考资料:

系统设计中使用的一些模块:
Jakarta Lucene:
http://jakarta.apache.org/lucene/

Xerces / Xalan
http://xml.apache.org/

Log4j
http://jakarta.apache.org/log4j/

Google的XML接口定义:
http://www.google.com/google.dtd

时间: 2025-01-19 16:53:28

基于Lucene/XML的站内全文检索解决方案的相关文章

使用Lucene.NET实现站内搜索

  提到Lucene,想必大家都有所耳闻,已经是数年前就出现的开源技术.很多站点都是利用它搭建自己网站的站内搜索.由于最近也在做数据检索方面的东西,也学习了下Lucene.net的使用. 导入Lucene.NET 开发包 Lucene 是apache软件基金会一个开放源代码的全文检索引擎工具包,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎.Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的

翻出一篇老文章:php文本站内全文检索

全文检索 <?php  /****************************************************   原作者: uchinaboy    修改:lingshidao特点:无需mysql支持:速度快:无需设置路径,放在哪级目录下,就搜索该目录和子目录:可以搜索一切文本类型的文件:显示文件相关内容:关键词自动高亮显示.修改内容:增加了自动分页和风格设置文件.搜索框代码(如果放在search.php相同目录下,无需修改):<form method="pos

图片-php中站内搜索,这个该如何修改

问题描述 php中站内搜索,这个该如何修改 解决方案 PHP站内搜索PHP 站内搜索PHP站内搜索 解决方案二: PHP也有分词一说.

使用过lucene.net的进来帮忙看一下,做过站内搜索的帮忙看一下

问题描述 新手,想改一下站内搜索,以前用的是sqlserver的全文索引,想改为lucene.net,建立完了索引,用的是lucene.net2.9.2,配合盘古分词器,能搜,但是结果不是很让人满意.想问下关于如何优化搜索结果的问题举例来说吧,假如我搜"程序员的自我修养",开头基本还算匹配,一共找出一万多条数据,但是后面的数据,都是匹配一个字的,例如"程序员的自我修养"把"大千的世界无奇不有"也给匹配出来了.也就是"的"字都给

关于lucene.net站内搜索的简单问题

问题描述 关于lucene.net站内搜索的简单问题 我做了一个简单的站内搜索,但是创建索引后无法搜索到数据,不知道为什么 #region 创建索引 public void createIndex() { SqlConnection conn = new SqlConnection("server=localhost;database=news;uid=sa;pwd=intellitrans"); FSDirectory directory; IndexWriter writer; s

基于ASP的站内多值搜索

  运行环境:IIS脚本语言:VBScript数据库:Access/SQL Server数据库语言:SQL 1.概要:不论是在论坛,还是新闻系统,或是下载系统等动态网站中,大家经常会看到搜索功能:搜索帖子,搜索用户,搜索软件(总之搜索关键字)等,本文则是介绍如何建立一个高效实用的,基于ASP的站内多值搜索. 本文面对的是"多条件模糊匹配搜索",理解了多条件的,单一条件搜索也不过小菜一碟了.一般来讲,有两种方法进行多条件搜索:枚举法和递进法.搜索条件不太多时(n<=3),可使用枚举

lucene.net站内搜索找不到数据

问题描述 lucene.net站内搜索找不到数据 不知道哪里错了,就是搜索的时候找不到数据.求大神帮忙看一下哪错了

几种常见的基于Lucene的开源搜索解决方案对比

一  直接使用 Lucene  ( http://lucene.apache.org ) 说明:Lucene 是一个 JAVA 搜索类库,它本身并不是一个完整的解决方案,需要额外的开发工作 优点:成熟的解决方案,有很多的成功案例.apache 顶级项目,正在持续快速的进步.庞大而活跃的开发社区,大量的开发人员.它只是一个类库,有足够的定制和优化空间:经过简单定制,就可以满足绝大部分常见的需求:经过优化,可以支持 10亿+ 量级的搜索. 缺点:需要额外的开发工作.所有的扩展,分布式,可靠性等都需要

再谈compass:集成站内搜索

前段时间已经写了一篇关于compass的文章,相信大家对compass也已经有了一定的了解 由于最近做的项目中涉及到了站内搜索,而且是基于JPA注解形式的,在网上找了好久,关于JPA集成compass的例子很少,有些也是基于 xml的,基于注解形式的甚是少,没有办法只有去compass的官网下载英文文档自己研究一下,花费了一下午时间调试出来,集成到项目中! 在这里给大家分享下,希望大家可以少走些弯路! 1.去官方网站下载compass的jar包,我用的的2.1版本 http://www.comp