??xml version="1.0" encoding="utf-8" standalone="yes"?>99re视频在线观看,日韩欧美电影在线观看,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 发表评论
]]>
վ֩ģ壺 ֦| | ͨ| | ǡ| | ͨ| | ǿ| | | | մ| | | | ֦| | | | Դ| | | | | | Ҧ| | Ͽ| ˱| | ʯ| | | | ̨| | | | | |