??xml version="1.0" encoding="utf-8" standalone="yes"?>懂色一区二区三区免费观看,欧美日韩精品一区二区三区在线观看 ,91精品国产一区二区三区动漫http://www.aygfsteel.com/caizh2009/category/41441.html与大家共同成?/description>zh-cnSun, 27 Sep 2009 09:05:24 GMTSun, 27 Sep 2009 09:05:24 GMT60nutch初体?/title><link>http://www.aygfsteel.com/caizh2009/archive/2009/09/24/296272.html</link><dc:creator>菜毛毛</dc:creator><author>菜毛毛</author><pubDate>Thu, 24 Sep 2009 04:58:00 GMT</pubDate><guid>http://www.aygfsteel.com/caizh2009/archive/2009/09/24/296272.html</guid><wfw:comment>http://www.aygfsteel.com/caizh2009/comments/296272.html</wfw:comment><comments>http://www.aygfsteel.com/caizh2009/archive/2009/09/24/296272.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/caizh2009/comments/commentRss/296272.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/caizh2009/services/trackbacks/296272.html</trackback:ping><description><![CDATA[<div id="wmqeeuq" class="asset-body"> <p>前几天看到卢亮的 <a >Larbin 一U高效的搜烦引擎爬虫工具</a> 一文提?<a >Nutch</a>Q很是感兴趣Q但一直没有时间进行测试研I。趁着假期Q先试一下看看。用搜烦引擎查找了一下,发现中文技术社区对 <a >Larbin</a> 的关注要q远大于 Nutch 。只有一q多前何东在他的<a >竹笋炒肉</a>中对 Nutch q行了一?a >介绍</a>?/p> </div> <div id="wmqeeuq" class="asset-more" id="more"> <p><strong>Nutch vs Lucene</strong> <br /> Lucene 不是完整的应用程序,而是一个用于实现全文检索的软g库?br /> Nutch 是一个应用程序,可以?Lucene 为基实现搜烦引擎应用?/p> <p><strong>Nutch vs GRUB</strong><br /> <a >GRUB</a> 是一个分布式搜烦引擎(<a >参?/a>)。用户只能得到客L工具(只有客户端是开源的)Q其目的在于利用用户的资源徏立集中式的搜索引擎?br /> Nutch 是开源的Q可以徏立自己内部网的搜索引擎,也可以针Ҏ个网l徏立搜索引擎。自?Free)而免?Free)?/p> <p><strong>Nutch vs Larbin</strong><br /> "Larbin只是一个爬虫,也就是说larbin只抓取网,至于如何parse的事情则q戯己完成。另外,如何存储到数据库以及建立索引的事?larbin也不提供。E引自<a >q里</a>Q?br /> Nutch 则还可以存储到数据库q徏立烦引?br /> <img height="220" alt="Nutch Architecture.png" src="http://www.dbanotes.net/archives/images/Nutch%20Architecture.png" width="316" /> <br /> Qd?a >q里</a>Q?</p> <p>Nutch 的早期版本不支持中文搜烦Q而最新的版本(2004-Aug-04 发布?<a >0.5</a>)已经做了很大的改q。相对先前的 0.4 版本Q有 20 多项的改q,l构上也更具备扩展性?.5 版经q测试,对中文搜索支持的也很好?/p> <p>下面是我的测试过E?/p> <p>前提条g(q里Linux ZQ如果是 Windows 参见手册)Q?/p> <ul> <li>Java 1.4.x 。因为我的系l上安装的Oracle 10g 已经?Java 了。设定环境变量:NUTCH_JAVA_HOME ? <blockquote> <pre>[root@fc3 ~]# export NUTCH_JAVA_HOME=/u01/app/oracle/product/10.1.0/db_1/jdk/jre </pre> </blockquote> <li>Tomcat 4.x 。从<a >q里</a>下蝲? <li>_的磁盘空间。我预留?4G 的空间?</li> </ul> <p>首先下蝲最新的E_版:</p> <blockquote> <pre>[root@fc3 ~]# wget http://www.nutch.org/release/nutch-0.5.tar.gz </pre> </blockquote> <p>解压~?</p> <blockquote> <pre>[root@fc3 ~]# tar -zxvf nutch-0.5.tar.gz ...... [root@fc3 ~]# mv nutch-0.5 nutch </pre> </blockquote> <p>试一?nutch 命oQ?/p> <blockquote> <pre>[root@fc3 nutch]# bin/nutch Usage: nutch COMMAND where COMMAND is one of: crawl one-step crawler for intranets admin database administration, including creation inject inject new urls into the database generate generate new segments to fetch fetchlist print the fetchlist of a segment fetch fetch a segment's pages dump dump a segment's pages index run the indexer on a segment's fetcher output merge merge several segment indexes dedup remove duplicates from a set of segment indexes updatedb update database from a segment's fetcher output mergesegs merge multiple segments into a single segment readdb examine arbitrary fields of the database analyze adjust database link-analysis scoring server run a search server or CLASSNAME run the class named CLASSNAME Most commands print help when invoked w/o parameters. [root@fc3 nutch]# </pre> </blockquote> <p>Nutch 的爬虫有两种方式</p> <ul> <li>爬行企业内部|?Intranet crawling)。针对少数网站进行。用 <em>crawl</em> 命o? <li>爬行整个互联|?使用低层?<em>inject, generate, fetch</em> ?<em>updatedb</em> 命o。具有更强的可控制性?</li> </ul> <p>以本?http://www.dbanotes.net)ZQ先q行一下针对企业内部网的测试?/p> ?nutch 目录中创Z个包含该|站|址的文?urls Q包含如下内容: <blockquote> <pre>http://www.dbanotes.net/ </pre> </blockquote> <p>然后~辑conf/crawl-urlfilter.txt 文gQ设定过滤信息,我这里只修改了MY.DOMAIN.NAME:</p> <blockquote> <pre># accept hosts in MY.DOMAIN.NAME +^http://([a-z0-9]*\.)*dbanotes.net/ </pre> </blockquote> <p>q行如下命o开始抓取分析网站内容:</p> <blockquote> <pre>[root@fc3 nutch]# bin/nutch crawl urls -dir crawl.demo -depth 2 -threads 4 >& crawl.log </pre> </blockquote> <p>depth 参数指爬行的深度Q这里处于测试的目的Q选择深度?2 Q?br /> threads 参数指定q发的进E?q是讑֮?4 Q?/p> <p>在该命oq行的过E中Q可以从 crawl.log 中查?nutch 的行Z及过E?</p> <blockquote> <pre>...... 050102 200336 loading file:/u01/nutch/conf/nutch-site.xml 050102 200336 crawl started in: crawl.demo 050102 200336 rootUrlFile = urls 050102 200336 threads = 4 050102 200336 depth = 2 050102 200336 Created webdb at crawl.demo/db ...... 050102 200336 loading file:/u01/nutch/conf/nutch-site.xml 050102 200336 crawl started in: crawl.demo 050102 200336 rootUrlFile = urls 050102 200336 threads = 4 050102 200336 depth = 2 050102 200336 Created webdb at crawl.demo/db 050102 200336 Starting <acronym title="Unified Resource Locator ">URL</acronym> processing 050102 200336 <strong>Using <acronym title="Unified Resource Locator ">URL</acronym> filter: net.nutch.net.RegexURLFilter</strong> ...... 050102 200337 Plugins: looking in: /u01/nutch/plugins 050102 200337 parsing: /u01/nutch/plugins/parse-html/plugin.xml 050102 200337 parsing: /u01/nutch/plugins/parse-pdf/plugin.xml 050102 200337 parsing: /u01/nutch/plugins/parse-ext/plugin.xml 050102 200337 parsing: /u01/nutch/plugins/parse-msword/plugin.xml 050102 200337 parsing: /u01/nutch/plugins/query-site/plugin.xml 050102 200337 parsing: /u01/nutch/plugins/protocol-http/plugin.xml 050102 200337 parsing: /u01/nutch/plugins/creativecommons/plugin.xml 050102 200337 parsing: /u01/nutch/plugins/language-identifier/plugin.xml 050102 200337 parsing: /u01/nutch/plugins/query-basic/plugin.xml 050102 200337 logging at INFO 050102 200337 fetching http://www.dbanotes.net/ 050102 200337 http.proxy.host = null 050102 200337 http.proxy.port = 8080 050102 200337 http.timeout = 10000 050102 200337 http.content.limit = 65536 050102 200337 http.agent = NutchCVS/0.05 (Nutch; http://www.nutch.org/docs/en/bot.html; n utch-agent@lists.sourceforge.net) 050102 200337 fetcher.server.delay = 1000 050102 200337 http.max.delays = 100 050102 200338 http://www.dbanotes.net/: setting encoding to GB18030 050102 200338 <acronym title="Creative Commons ">CC</acronym>: found http://creativecommons.org/licenses/by-nc-sa/2.0/ in rdf of http: //www.dbanotes.net/ 050102 200338 <acronym title="Creative Commons ">CC</acronym>: found text in http://www.dbanotes.net/ 050102 200338 status: 1 pages, 0 errors, 12445 bytes, 1067 ms 050102 200338 status: 0.9372071 pages/s, 91.12142 kb/s, 12445.0 bytes/page 050102 200339 Updating crawl.demo/db 050102 200339 Updating for crawl.demo/segments/20050102200336 050102 200339 Finishing update 64,1 7% 050102 200337 parsing: /u01/nutch/plugins/query-basic/plugin.xml 050102 200337 logging at INFO 050102 200337 fetching http://www.dbanotes.net/ 050102 200337 http.proxy.host = null 050102 200337 http.proxy.port = 8080 050102 200337 http.timeout = 10000 050102 200337 http.content.limit = 65536 050102 200337 http.agent = NutchCVS/0.05 (Nutch; http://www.nutch.org/docs/en/bot.html; nutch-agent@lists.sourceforge.net) 050102 200337 fetcher.server.delay = 1000 050102 200337 http.max.delays = 100 ...... </pre> </blockquote> <p>之后配置 Tomcat (我的 tomcat 安装?/opt/Tomcat) Q?</p> <blockquote> <pre>[root@fc3 nutch]# rm -rf /opt/Tomcat/webapps/ROOT* [root@fc3 nutch]# cp nutch*.war /opt/Tomcat/webapps/ROOT.war [root@fc3 webapps]# cd /opt/Tomcat/webapps/ [root@fc3 webapps]# jar xvf ROOT.war [root@fc3 webapps]# ../bin/catalina.sh start </pre> </blockquote> <p>览器中输入 http://localhost:8080 查看l果(q程查看需要将 localhost 换成相应的IP)Q?/p> <img height="360" alt="nutch web search interface.png" src="http://www.dbanotes.net/archives/images/nutch%20web%20search%20interface.png" width="648" /> <p>搜烦试Q?/p> <img height="367" alt="nutch web search result.png" src="http://www.dbanotes.net/archives/images/nutch%20web%20search%20result.png" width="650" /> <p>可以看到QNutch 亦提供快照功能。下面进行中文搜索测?</p> <img height="380" alt="nutch web Chinese search result.png" src="http://www.dbanotes.net/archives/images/nutch%20web%20Chinese%20search%20result.png" width="654" /> <p>注意l果中的那个“评分详解”Q是个很有意思的功能(Nutch h一个链接分析模?Q通过q些数据可以q一步理解该法?/p> <p>考虑到带宽的限制Q暂时不Ҏ个Web爬行的方式进行了试了。值得一提的是,在测试的q程中,nutch 的爬行速度q是不错?相对我的p糕带宽)?/p> <p>Nutch 目前q不支持 <strong><acronym title="Portable Document Format ">PDF</acronym></strong>(开发中Q不够完? ?<strong>囄</strong> {对象的搜烦?strong>中文分词技?/strong>q不够好Q通过“评分详解”可看出,对中文,比如“数据库管理员”Q是分成单独的字q行处理的。但作ؓ一个开源搜索引擎YӞ功能是可圈可点的。毕竟,主要开发?<a >Doug Cutting</a> 是开?<a >Lucene</a> 的大?/p> <p>参考信?/p> <ul> <li><a >Nutch Wiki</a> - http://www.nutch.org/cgi-bin/twiki/view/Main/Nutch <li>何东?<a >试用Nutch</a> <li>车东?<a >LuceneQ基于Java的全文检索引擎简?/a> </li> </ul> </div> <img src ="http://www.aygfsteel.com/caizh2009/aggbug/296272.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/caizh2009/" target="_blank">菜毛毛</a> 2009-09-24 12:58 <a href="http://www.aygfsteel.com/caizh2009/archive/2009/09/24/296272.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>http://www.lucene.com.cn/ LUCENE.COM.CN 中国 http://www.aygfsteel.com/caizh2009/archive/2009/09/24/296270.html菜毛毛菜毛毛Thu, 24 Sep 2009 04:54:00 GMThttp://www.aygfsteel.com/caizh2009/archive/2009/09/24/296270.htmlhttp://www.aygfsteel.com/caizh2009/comments/296270.htmlhttp://www.aygfsteel.com/caizh2009/archive/2009/09/24/296270.html#Feedback0http://www.aygfsteel.com/caizh2009/comments/commentRss/296270.htmlhttp://www.aygfsteel.com/caizh2009/services/trackbacks/296270.html

菜毛毛 2009-09-24 12:54 发表评论
]]>
nutch和lucene的区?/title><link>http://www.aygfsteel.com/caizh2009/archive/2009/09/24/296269.html</link><dc:creator>菜毛毛</dc:creator><author>菜毛毛</author><pubDate>Thu, 24 Sep 2009 04:53:00 GMT</pubDate><guid>http://www.aygfsteel.com/caizh2009/archive/2009/09/24/296269.html</guid><wfw:comment>http://www.aygfsteel.com/caizh2009/comments/296269.html</wfw:comment><comments>http://www.aygfsteel.com/caizh2009/archive/2009/09/24/296269.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/caizh2009/comments/commentRss/296269.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/caizh2009/services/trackbacks/296269.html</trackback:ping><description><![CDATA[<p>惛_一个搜索引擎,最q浏览了许多C֌Q发现Lucene和Nutch用的很多Q而这两个我L觉难以区分概念,于是在查了些资料。下面是Lucene和Nutch创始人Doug Cutting 的访谈摘录:</p> <p> Lucene其实是一个提供全文文本搜索的函数库,它不是一个应用Y件。它提供很多API函数让你可以q用到各U实际应用程序中。现在,它已l成为Apache的一个项目ƈ被广泛应用着。这里列Z些已l用Lucene的系l?/p> <p>Nutch是一个徏立在Lucene核心之上的Web搜烦的实玎ͼ它是一个真正的应用E序。也是_你可以直接下载下来拿q来用。它在Lucene的基上加了网l爬虫和一些和Web相关的东东。其目的是想从一个简单的站内索引和搜索推q到全球|络的搜索上Q就像Google和Yahoo一栗当Ӟ和那些巨人竞争,你得动一些脑{,想一些办法。我们已l测试过100M的网,q且它的设计用在过1B的网上应该没有问题。当Ӟ让它q行在一台机器上Q搜索一些服务器Q也q行的很好?/p> <p>   ȝ来说Q我认ؓLUCENE会应用在本地服务器的|站内部搜烦Q而Nutch则扩展到整个|络、Internet的检索。当然LUCENE加上爬虫E序{就会成为NutchQ这L解应该没错吧</p> <p><br /> 本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/rokii/archive/2008/03/01/2137450.aspx</p> <img src ="http://www.aygfsteel.com/caizh2009/aggbug/296269.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/caizh2009/" target="_blank">菜毛毛</a> 2009-09-24 12:53 <a href="http://www.aygfsteel.com/caizh2009/archive/2009/09/24/296269.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 Apache Lucene 搜烦文本http://www.aygfsteel.com/caizh2009/archive/2009/09/17/295491.html菜毛毛菜毛毛Thu, 17 Sep 2009 11:45:00 GMThttp://www.aygfsteel.com/caizh2009/archive/2009/09/17/295491.htmlhttp://www.aygfsteel.com/caizh2009/comments/295491.htmlhttp://www.aygfsteel.com/caizh2009/archive/2009/09/17/295491.html#Feedback0http://www.aygfsteel.com/caizh2009/comments/commentRss/295491.htmlhttp://www.aygfsteel.com/caizh2009/services/trackbacks/295491.html阅读全文

菜毛毛 2009-09-17 19:45 发表评论
]]>
使用 Java 开源工具徏立一个灵zȝ搜烦引擎http://www.aygfsteel.com/caizh2009/archive/2009/08/29/293035.html菜毛毛菜毛毛Fri, 28 Aug 2009 16:25:00 GMThttp://www.aygfsteel.com/caizh2009/archive/2009/08/29/293035.htmlhttp://www.aygfsteel.com/caizh2009/comments/293035.htmlhttp://www.aygfsteel.com/caizh2009/archive/2009/08/29/293035.html#Feedback0http://www.aygfsteel.com/caizh2009/comments/commentRss/293035.htmlhttp://www.aygfsteel.com/caizh2009/services/trackbacks/293035.html为应用程序添加搜索能力经常是一个常见的需求。本文介l了一个框Ӟ开发者可以用它以最的付出实现搜烦引擎功能Q理x况下只需要一个配|文件。该框架Z若干开源的库和工具Q如 Apache LuceneQSpring 框架Qcpdetector {。它支持多种资源。其中两个典型的例子是数据库资源和文件系l资源。Indexer 寚w|的资源q行索引q传输到中央服务器,之后q些索引可以通过 API q行搜烦。Spring 风格的配|文件允许清晰灵zȝ自定义和调整。核?API 也提供了可扩展的接口?
引言

为应用程序添加搜索能力经常是一个常见的需求。尽已l有若干E序库提供了Ҏ索基设施的支持,然而对于很多h而言Q用它们从头开始徏立一个搜索引擎将是一个付Z而且可能乏味的过E。另一斚wQ很多的型应用对于搜烦功能的需求和应用场景h很大的相似性。本文试图以对多数小型应用的适用性ؓ出发点,?Java 语言构徏一个灵zȝ搜烦引擎框架。用这个框Ӟ多数情Ş下可以以最的付出建立起一个搜索引擎。最理想的情况下Q甚臛_需要一个配|文件。特D的情Ş下,可以通过灉|地对框架q行扩展满需求。当Ӟ如题所qͼq都是借助开源工L力量?


基础知识

Apache Lucene 是开发搜索类应用E序时最常用?Java cdQ我们的框架也将Z它。ؓ了下文更好的描述Q我们需要先了解一些有?Lucene 和搜索的基础知识。注意,本文不关注烦引的文g格式、分词技术等话题?

什么是搜烦和烦?/span>

从用L角度来看Q搜索的q程是通过关键字在某种资源中寻扄定的内容的过E。而从计算机的角度来看Q实现这个过E可以有两种办法。一是对所有资源逐个与关键字匚wQ返回所有满_配的内容Q二是如同字怸样事先徏立一个对应表Q把关键字与资源的内容对应v来,搜烦时直接查找这个表卛_。显而易见,W二个办法效率要高得多。徏立这个对应表事实上就是徏立逆向索引Qinverted indexQ的q程?
Lucene 基本概念

Lucene ?Doug Cutting ?Java 开发的用于全文搜烦的工具库。在q里Q我假设读者对其已有基本的了解Q我们只对一些重要的概念要介l。要深入了解可以参?参考资?中列出的相关文章和图书。下面这些是 Lucene 里比较重要的cR?
DocumentQ烦引包含多?Document。而每?Document 则包含多?Field 对象。Document 可以是从数据库表里取出的一堆数据,可以是一个文Ӟ也可以是一个网늭。注意,它不{同于文件系l中的文件?
FieldQ一?Field 有一个名Uͼ它对?Document的一部分数据Q表C文的内容或者文的元数据(与下文中提到的资源元数据不是一个概念)。一?Field 对象有两个重要属性:Store ( 可以?YES, NO, COMPACT 三种取?) ?Index ( 可以?TOKENIZED, UN_TOKENIZED, NO, NO_NORMS 四种取?)
QueryQ抽象了搜烦时用的语句?
IndexSearcherQ提供Query对象l它Q它利用已有的烦引进行搜索ƈq回搜烦l果?
HitsQ一个容器,包含了指向一部分搜烦l果的指针?
使用 Lucene 来进行编制烦引的q程大致为:输入的数据源统一为字W串或者文本流的Ş式,然后从数据源提取数据Q创建合适的 Field d到对应该数据源的 Document 对象之中?


pȝ概览

要徏立一个通用的框Ӟ必须对不同情늚共性进行抽象。反映到设计需要注意两炏V一是要提供扩展接口Q二是要量降低模块之间的耦合E度。我们的框架很简单地分ؓ两个模块Q烦引模块和搜烦模块。烦引模块在不同的机器上各自q行对资源的索引Qƈ把烦引文Ӟ事实上,下面我们会说刎ͼq有元数据)l一传输到同一个地方(可以是在q程服务器上Q也可以是在本地Q。搜索模块则利用q些从多个烦引模块收集到的数据完成用L搜烦h?/span>

?1 展现了整体的框架。可以看刎ͼ两个模块之间相对是独立的Q它们之间的兌不是通过代码Q而是通过索引和元数据。在下文中,我们会详细介绍如何Z开源工兯计和实现q两个模块?/span>


?1. pȝ架构?/span>


建立索引

可以q行索引的对象有很多Q如文g、网cRSS Feed {。在我们的框架中Q我们定义可以进行烦引的一cd象ؓ资源。从实现l节上来_从一个资源中可以提取出多?Document 对象。文件系l资源和数据库结果集资源都是资源的代表性例子?/span>

前面提到Q从资源中收集到的烦引被l一传送到同一个地方,以被搜烦模块所用。显焉了烦引之外,搜烦模块需要有对资源更多的了解Q如资源的名U、搜索该资源后搜索结果的呈现格式{。这些额外的附加信息UCؓ资源的元数据。元数据和烦引数据一同被攉hQ放|到某个特定的位|?/span>

要地介绍q资源的概念之后Q我们首先ؓ其定义一?Resource 接口。这个接口的声明如下?/span>


清单 1. Resource 接口
public interface Resource {
// RequestProcessor 对象被动C资源中提?DocumentQƈq回提取的数?/span>
public int extractDocuments(ResourceProcessor processor);

// d?DocumentListener 在每一?Document 对象被提取出时被调用
public void addDocumentListener(DocumentListener l);

// q回资源的元数据
public ResourceMetaData getMetaData();
}


其中元数据包含的字段见下表。在下文中,我们q会对元数据的用途做更多的介l?/span>


?1. 资源元数据包含的字段
属?cd 含义
resourceName String 资源的唯一名称
resourceDescription String 资源的介l性文?
hitTextPattern String 当文被搜烦到时Q这?pattern 规定了结果显C的格式
searchableFields String[] 可以被搜索的字段名称

?DocumentListener 的代码如下?/span>


清单 2. DocumentListener 接口
public interface DocumentListener extends EventListener {
public void documentExtracted(Document doc);
}



Z让烦引模块能够知道所有需要被索引的资源,我们在这里?Spring 风格?XML 文g配置索引模块中的所有组Ӟ其是所有资源。您可以?下蝲部分 查看一个示例配|文件?/span>

Z么选择使用 Spring 风格的配|文Ӟ

q主要有两个好处Q?

仅依赖于 Spring Core ?Spring Beans 便免M定义配置机制和解析配|文件的负担Q?
Spring ?IoC 机制降低了框架的耦合性,q扩展框架变得单;



Z以上内容Q我们可以大致描q出索引模块工作的过E:

首先?XML 配置?bean 中找出所?Resource 对象Q?
Ҏ一个调用其 extractDocuments() ҎQ这一步除了完成对资源的烦引外Q还会在每次提取Z?Document 对象之后Q通知注册在该资源上的所?DocumentListenerQ?
接着处理资源的元数据QgetMetaData() 的返回|Q?
缓存里的数据写入到本地盘或者传送给q程服务器;

在这个过E中Q有两个地方值得注意?/span>

W一Q对资源可以注册 DocumentListener 使得我们可以在运行时d索引q程有更为动态的控制。D一个简单例子,Ҏ个文章发布站点的文章q行索引Ӟ一个很正常的要求便是发布时间更靠近当前旉的文章需要在搜烦l果中排在靠前的位置。每文章显然对应一?Document 对象Q在 Lucene 中我们可以通过讄 Document ?boost 值来对其q行加权。假讑օ中文章发布时间的 Field 的名UCؓ PUB_TIMEQ那么我们可以ؓ资源注册一?DocumentListenerQ当它被通知Ӟ则检?PUB_TIME 的|Ҏ距离当前旉的远q进行加权?/span>

W二点很昄Q在q个q程中,extractDocuments() Ҏ的实C不同cd的资源而各异。下面我们主要讨ZU类型的资源Q文件系l资源和数据库结果集资源。这两个c都实现了上面的 接口?/span>

文gpȝ资源

Ҏ件系l资源的索引通常从一个基目录开始,递归处理每个需要进行烦引的文g。该资源有一个字W串数组cd?excludedFiles 属性,表示在处理文件时需要排除的文gl对路径的正则表辑ּ。在递归遍历文gpȝ树的同时Q绝对\径匹?excludedFiles 中Q意一的文g不会被处理。这主要是考虑C般我们只需要对一部分文g夹(比如排除可能存在的备份目录)中的一部分文gQ如 doc, ppt 文g{)q行索引?/span>

除了所有文件共有的文g名、文件\径、文件大和修改旉{?FieldQ不同类型的文g需要有不同的处理方法。ؓ了保留灵zL,我们使用 Strategy 模式装对不同类型文件的处理方式。ؓ此我们抽象出一?DocumentBuilder 的接口,该接口仅定义了一个方法如下:


清单 3. DocumentBuilder 接口
public interface DocumentBuilder {
Document buildDocument(InputStream is);
}

什么是 Strategy 模式Q?/span>

Ҏ Design patterns: Elements of reusable object orientated software 一书:Strategy 模式“定义一pd的算法,把它们分别封装v来,q且使它们相互可以替换。这个模式得算法可以独立于使用它的客户而变化?#8221;


不同?DocumentBuilderQStrategyQ?用于从一个输入流中读取数据,处理不同cd的文件。对于常见的文g格式来说Q都有合适的开源工具帮助进行解析。在下表中我们列举一些常见文件类型的解析办法?/span>

文gcd 常用扩展?可以使用的解析办?
U文本文?txt 无需cd解析
RTF 文 rtf 使用 javax.swing.text.rtf.RTFEditorKit c?
Word 文档Q非 OOXML 格式Q?doc Apache POI Q可配合使用 POI ScratchpadQ?
PowerPoint 演示文稿Q非 OOXML 格式Q?xls Apache POI Q可配合使用 POI ScratchpadQ?
PDF 文档 pdf PDFBoxQ可能中文支持欠佻I
HTML 文 htm, html JTidy, Cobra

q里?Word 文gZQ给Z个简单的参考实现?/span>


清单 4. 解析U文本内容的实现
// WordDocument ?Apache POI Scratchpad 中的一个类
Document buildDocument(InputStream is) {
String bodyText = null;
try {
WordDocument wordDoc = new WordDocument(is);
StringWriter sw = new StringWriter();
wordDoc.writeAllText(sw);
sw.close();
bodyText = sw.toString();
} catch (Exception e) {
throw new DocumentHandlerException("Cannot extract text from a Word document", e);
}
if ((bodyText != null) && (bodyText.trim().length() > 0)) {
Document doc = new Document();
doc.add(new Field("body", bodyText, Field.Store.YES, Field.Index.TOKENIZED));
return doc;
}
return null;
}



那么如何选择合适的 Strategy 来处理文件呢QUNIX pȝ下的 file(1) 工具提供了从 magicnumber 获取文gcd的功能,我们可以使用 Runtime.exec() Ҏ调用q一命o。但q需要在?file(1) 命o的情况下Q而且q不能识别出所有文件类型。在一般的情况下我们可以简单地Ҏ扩展名来使用合适的cd理文件。扩展名和类的映关pd?properties 文g中。当需要添加对新的文gcd的支持时Q我们只需d一个新的实?DocumentBuilder 接口的类Qƈ在映文件中d一个映关pd可?/span>

数据库结果集资源

大多数应用用数据库作ؓ怹存储Q对数据库查询结果集索引是一个常见需求?/span>

生成一个数据库l果集资源的实例需要先提供一个查询语句,然后执行查询Q得C个结果集。这个结果集中的内容便是我们需要进行烦引的对象。extractDocuments 的实C是ؓl果集中的每一行创Z?Document 对象。和文gpȝ资源不同的是Q数据库资源需要放?Document 中的 Field 一般都存在在查询结果集之中。比如一个简单的文章发布站点Q对其后台数据库执行查询 SELECT ID, TITLE, CONTENT FROM ARTICLE q回一个有三列的结果集。对l果集的每一行都会被提取Z?Document 对象Q其中包含三?FieldQ分别对应这三列?/span>

然而不?Field 的类型是不同的。比?ID 字段一般对?Store.YES ?Index.NO ?FieldQ?TITLE 字段则一般对?Store.YES ?Index.TOKENIZED ?Field。ؓ了解册个问题,我们在数据库l果集资源的实现中提供一个类型ؓ Properties ?fieldTypeMappings 属性,用于讄数据库字D|对应?Field 的类型。对于前面的情况来说Q这个属性可能会被配|成cMq样的Ş式:

ID = YES, NO
TITLE = YES, TOKENIZED
CONTENT = NO, TOKENIZED


配合q个映射Q我们便可以生成合适类型的 FieldQ完成对l果集烦引的工作?/span>


攉索引

完成对资源的索引之后Q还需要让索引为搜索模块所用。前面我们已l说q这里介l的框架主要用于型应用Q考虑到复杂性,我们采取单地分布在各个机器上的索引汇d一个地方的{略?/span>

汇ȝ引的传输方式可以有很多方案,比如使用 FTP、HTTP、rsync {。甚至烦引模块和搜烦模块可以位于同一台机器上Q这U情况下只需要将索引q行本地拯卛_。同前面cMQ我们定义一?Transporter 接口?/span>


清单 5. Transporter 接口
public interface Transporter {
public void transport(File file);
}


?FTP 方式传输ZQ我们?Commons Net 完成传输的操作?/span>

public void transport(File file) throws TransportException {
FTPClient client = new FTPClient();
client.connect(host);
client.login(username, password);
client.changeWorkingDirectory(remotePath);
transportRecursive(client, file);
client.disconnect();
}

public void transportRecursive(FTPClient client, File file) {
if (file.isFile() && file.canRead()) {
client.storeFile(file.getName(), new FileInputStream(file));
} else if (file.isDirectory()) {
client.makeDirectory(file.getName());
client.changeWorkingDirectory(file.getName());
File[] fileList = file.listFiles();
for (File f : fileList) {
transportRecursive(client, f);
}
}
}



对其他传输方案也有各自的Ҏq行处理Q具体用哪?Transporter 的实现被配置?Spring 风格的烦引模块配|文件中。传输的方式是灵zȝ。比如当需要强调安全性时Q我们可以换用基?SSL ?FTP q行传输。所需要做的只是开发一个?FTP over SSL ?Transporter 实现Qƈ在配|文件中更改 Transporter 的实现即可?/span>

q行搜烦

在做了这么多之后Q我们开始接触和用户兌最为紧密的搜烦模块。注意,我们的框架不包括一个基于已l收集好的烦引进行搜索是个很单的q程。Lucene 已经提供了功能强大的 IndexSearcher 及其子类。在q个部分Q我们不会再介绍如何使用q些c,而是x在前文提到过的资源元数据上。元数据从各个资源所在的文g夹中d得到Q它在搜索模块中扮演重要的角艌Ӏ?/span>

构徏一个查?/span>

对不同资源进行搜索的查询Ҏq不一栗例如搜索一个论坛里的所有留aӞ我们x的一般是留言的标题、作者和内容Q而当搜烦一?FTP 站点Ӟ我们更多x的是文g名和文g内容。另一斚wQ我们有时可能会使用一个查询去搜烦多个资源的结果。这正是之前我们在前面所提到的元数据?searchableFields ?resourceName 属性的作用。前者指Z个资源中哪些字段是参与搜索的Q后者则用于在搜索时定使用哪个或者哪些烦引。从技术细节来_只有有了q些信息Q我们才可以构造出可用?Query 对象?/span>

呈现搜烦l果

当从 IndexSearcher 对象得到搜烦l果QHitsQ之后,当然我们可以直接从中获取需要的|再格式化予以输出。但一来格式化输出搜烦l果Q尤其在 Web 应用中)是个很常见的需求,可能会经常变_二来l果的呈现格式应该是由分散的资源各自定义Q而不是交由搜索模块来定义。基于上面两个原因,我们的框架将使用在资源收集端配置l果输出格式的方式。这个格式由资源元数据中?hitTextPattern 属性定义。该属性是一个字W串cd的|支持两种语法

形如 ${field_name} 的子字符串都会被动态替换成查询l果中各?Document ?Field 的倹{?
形如 $function(...) 的被解释为函敎ͼ括号内以逗号隔开的符号都被解释成参数Q函数可以嵌套?
例如搜烦“具体”q回的搜索结果中包含一?Document 对象Q其 Field 如下表:

Field 名称 Field 内容
url http://example.org/article/1.html
title CZ标题
content q里是具体的内容?

那么如果 hitTextPatten 被设|ؓ“${title}
$highlight(${content}, 5, "", "")”Q返回的l果l浏览器解释后可能的昄l果如下Q这只是个演C链接,请不要点击)Q?/span>

CZ标题
q里是具?..

上面提到?$highlight() 函数用于在搜索结果中取得最匚w的一D|本,q亮显C搜索时使用的短语,其第一个参数是高亮昄的文本,W二个参数是昄的文本长度,W三和第四个参数是高亮文本时使用的前~和后~?/span>

可以使用正则表达式和文本解析来实现前面所提到的语法。我们也可以使用 JavaCC 定义 hitTextPattern 的文法,q而生成词法分析器和语法解析器。这是更为系lƈ且相对而言不易出错的方法。对 JavaCC 的介l不是本文的重点Q您可以在下面的 阅读资源 中找到学习资料?/span>

下面列出的是一些与我们所提出的框架所相关或者类似的产品Q您可以?学习资料 中更多地了解他们?/span>

IBM?OmniFind?Family

OmniFind ?IBM 公司推出的企业搜烦解决Ҏ。基?UIMA (Unstructured Information Management Architecture) 技术,它提供了强大的烦引和获取信息功能Q支持巨大数量、多U类型的文资源Q无论是l构化还是非l构化)Qƈ?Lotus?Domino??WebSphere?Portal 专门q行了优化?/span>

Apache Solr

Solr ?Apache 的一个企业的全文检索项目,实现了一个基?HTTP 的搜索服务器Q支持多U资源和 Web 界面理Q它同样建立?Lucene 之上Qƈ?Lucene 做了很多扩展Q例如支持动态字D及唯一键,Ҏ询结果进行动态分l和qo{?/span>

Google SiteSearch

使用 Google 的站Ҏ索功能可以方便而快捷地建立一个站内搜索引擎。但?Google 的站Ҏ索基?Google 的网l爬虫,所以无法访问受保护的站点内Ҏ?Intranet 上的资源。另外,Google 所支持的资源类型也是有限的Q我们无法对其进行扩展?/span>

SearchBlox?

SearchBlox 是一个商业的搜烦引擎构徏框架。它本n是一?J2EE lgQ和我们的框架类|也支持对|页和文件系l等资源q行索引Q进而进行搜索?/span>


q需考虑的问?/span>

本文介绍的思想试图利用开源的工具解决中小型应用中的常见问题。当Ӟ作ؓ一个框Ӟ它还有很多不I下面列DZ些可以进行改q的地方?/span>

性能考虑

当需要进行烦引的资源数目不多Ӟ隔一定的旉q行一ơ完全烦引不会占用很长时间。用一?2G 内存QXeon 2.66G 处理器的服务器进行实际测试,发现Ҏ据库资源的烦引占用的旉很少Q一千多条记录花费的旉?1 U到 2 U之内。而对 1400 多个文gq行索引耗时大约十几U。但在大型应用中Q资源的定w是巨大的Q如果每ơ都q行完整的烦引,耗费的时间会很惊人。我们可以通过跌已经索引的资源内容,删除已不存在的资源内容的索引Qƈq行增量索引来解册个问题。这可能会涉及文件校验和索引删除{?/span>

另一斚wQ框架可以提供查询缓存来提高查询效率。框架可以在内存中徏立一U缓存,q用如 OSCache ?EHCache 实现盘上的二~存。当索引的内容变化不频繁Ӟ使用查询~存更会明显地提高查询速度、降低资源消耗?/span>

分布式烦?/span>

我们的框架可以将索引分布在多台机器上。搜索资源时Q查询被 flood 到各个机器上从而获得搜索结果。这样可以免M输烦引到某一C央服务器的过E。当然也可以在非l构化的 P2P |络上实现分布式哈希?(DHT)Q配合烦引复?(Replication)Q得应用程序更为安全,可靠Q有伸羃性。在阅读资料中给Z 一关于构建分布式环境下全文搜索的可行性的论文?

安全?/span>

目前我们的框架ƈ没有涉及到安全性。除了依赖资源本w的讉K控制Q如受保护的|页和文件系l等Q之外,我们q可以从两方面增强框架本w的安全性:

考虑C个组l的搜烦功能对不同用L权限讄不一定一P可以支持对用戯色的定义Q实行对搜烦模块的访问控制?
在资源烦引模块中实现一U机Ӟ让资源可以限制自己暴露的内容Q从而羃烦引模块的索引范围。这可以cL robots 文g可以规定搜烦引擎爬虫的行为?


通过上文的介l,我们认识了一个可扩展的框Ӟq引模块和搜烦模块两部分组成。它可以灉|地适应不同的应用场景。如果需要更独特的需求,框架本n预留了可以扩展的接口Q我们可以通过实现q些接口完成功能的定制。更重要的是q一切都是徏立在开源Y件的基础之上。希望本文能为您揭示开源的力量Q体验用开源工L装您自己的解x案所带来的莫大快乐?/span>

菜毛毛 2009-08-29 00:25 发表评论
]]>
վ֩ģ壺 Ӽ| ԭ| | | | Զ| | | | »| | ֦| ɽ| | ɽ| ϲ| | Զ| ɽ| º| Ϣ| | | | Ϫ| | ľ| ˮ| | Ӣ| | | ˫| ɽ| Ҫ| | ³ľ| | ӽ| | ƺ|