﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-BaoYaEr-文章分类-Lucene</title><link>http://www.blogjava.net/baoyaer/category/20033.html</link><description>java</description><language>zh-cn</language><lastBuildDate>Fri, 18 Jan 2008 15:25:23 GMT</lastBuildDate><pubDate>Fri, 18 Jan 2008 15:25:23 GMT</pubDate><ttl>60</ttl><item><title>lucene全文检索应用示例及代码简析 </title><link>http://www.blogjava.net/baoyaer/articles/175099.html</link><dc:creator>大田斗</dc:creator><author>大田斗</author><pubDate>Mon, 14 Jan 2008 02:38:00 GMT</pubDate><guid>http://www.blogjava.net/baoyaer/articles/175099.html</guid><wfw:comment>http://www.blogjava.net/baoyaer/comments/175099.html</wfw:comment><comments>http://www.blogjava.net/baoyaer/articles/175099.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/baoyaer/comments/commentRss/175099.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/baoyaer/services/trackbacks/175099.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 使用Lucene实现全文检索，主要有下面三个步骤：　　1、建立索引库：根据网站新闻信息库中的已有的数据资料建立Lucene索引文件。　　2、通过索引库搜索：有了索引后，即可使用标准的词法分析器或直接的词法分析器实现进行全文检索。　　3、维护索引库：网站新闻信息库中的信息会不断的变动，包括新增、修改及删除等，这些信息的变动都需要进一步反映到Lucene索引文件中。&nbsp;&nbs...&nbsp;&nbsp;<a href='http://www.blogjava.net/baoyaer/articles/175099.html'>阅读全文</a><img src ="http://www.blogjava.net/baoyaer/aggbug/175099.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/baoyaer/" target="_blank">大田斗</a> 2008-01-14 10:38 <a href="http://www.blogjava.net/baoyaer/articles/175099.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>lucene实例使用</title><link>http://www.blogjava.net/baoyaer/articles/175096.html</link><dc:creator>大田斗</dc:creator><author>大田斗</author><pubDate>Mon, 14 Jan 2008 02:32:00 GMT</pubDate><guid>http://www.blogjava.net/baoyaer/articles/175096.html</guid><wfw:comment>http://www.blogjava.net/baoyaer/comments/175096.html</wfw:comment><comments>http://www.blogjava.net/baoyaer/articles/175096.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/baoyaer/comments/commentRss/175096.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/baoyaer/services/trackbacks/175096.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;说明一下,这一篇文章的用到的lucene,是用2.0版本的,主要在查询的时候2.0版本的lucene与以前的版本有了一些区别. 其实这一些代码都是早几个月写的,自己很懒,所以到今天才写到自己的博客上,高深的文章自己写不了，只能记录下一些简单的记录与点滴，其中的代码算是自娱自乐的，希望高手不要把重构之类的砸下来...1、在windows系统下的的C盘，建一个名叫s的文件夹,在...&nbsp;&nbsp;<a href='http://www.blogjava.net/baoyaer/articles/175096.html'>阅读全文</a><img src ="http://www.blogjava.net/baoyaer/aggbug/175096.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/baoyaer/" target="_blank">大田斗</a> 2008-01-14 10:32 <a href="http://www.blogjava.net/baoyaer/articles/175096.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lucene基本使用介绍</title><link>http://www.blogjava.net/baoyaer/articles/99661.html</link><dc:creator>大田斗</dc:creator><author>大田斗</author><pubDate>Tue, 13 Feb 2007 03:50:00 GMT</pubDate><guid>http://www.blogjava.net/baoyaer/articles/99661.html</guid><wfw:comment>http://www.blogjava.net/baoyaer/comments/99661.html</wfw:comment><comments>http://www.blogjava.net/baoyaer/articles/99661.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/baoyaer/comments/commentRss/99661.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/baoyaer/services/trackbacks/99661.html</trackback:ping><description><![CDATA[
		<div style="CLEAR: right">
				<p>今天用了下Lucene，发现网上虽然也有不少介绍它的文档，不过很多都偏向介绍概念呀、设计或者是一些更为深入的东西，对于其入门使用的介绍性的文档并不多，就写了这么一篇。<br /><br /></p>
				<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: 150%; TEXT-ALIGN: center" align="center">
						<b style="mso-bidi-font-weight: normal">
								<span lang="EN-US" style="FONT-SIZE: 16pt; LINE-HEIGHT: 150%">Lucene</span>
						</b>
						<b style="mso-bidi-font-weight: normal">
								<span style="FONT-SIZE: 16pt; LINE-HEIGHT: 150%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">基本使用介绍</span>
						</b>
						<b style="mso-bidi-font-weight: normal">
								<span lang="EN-US" style="FONT-SIZE: 16pt; LINE-HEIGHT: 150%">
										<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?>
										<o:p>
										</o:p>
								</span>
						</b>
				</p>
				<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: 150%; TEXT-ALIGN: center" align="center">
						<b style="mso-bidi-font-weight: normal">
								<span lang="EN-US" style="FONT-SIZE: 16pt; LINE-HEIGHT: 150%">
										<o:p> </o:p>
								</span>
						</b>
				</p>
				<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: 150%; TEXT-ALIGN: center" align="center">
						<span>本文的目的不在于对Lucene的概念和设计这些进行介绍，仅在于介绍怎么样去使用Lucene来达到自己想要的几种常见的全文检索的需求，如果想深入了解Lucene的话本文不会带给你什么收获的。看完本文后想更深入的了解Lucene请访问：<a href="http://lucene.apache.org/">http://lucene.apache.org</a><o:p></o:p></span>
				</p>
				<p> </p>
				<p>一.  概述</p>
				<p>随着系统信息的越来越多，怎么样从这些信息海洋中捞起自己想要的那一根针就变得非常重要了，全文检索是通常用于解决此类问题的方案，而Lucene则为实现全文检索的工具，任何应用都可通过嵌入它来实现全文检索。</p>
				<p>二.  环境搭建</p>
				<p>从lucene.apache.org上下载最新版本的lucene.jar，将此jar作为项目的build path，那么在项目中就可以直接使用lucene了。</p>
				<p>三.  使用说明</p>
				<p>3.1.       基本概念</p>
				<p>这里介绍的主要为在使用中经常碰到一些概念，以大家都比较熟悉的数据库来进行类比的讲解，使用Lucene进行全文检索的过程有点类似数据库的这个过程，table---à查询相应的字段或查询条件----à返回相应的记录，首先是IndexWriter，通过它建立相应的索引表，相当于数据库中的table，在构建此索引表时需指定的为该索引表采用何种方式进行构建，也就是说对于其中的记录的字段以什么方式来进行格式的划分，这个在Lucene中称为Analyzer，Lucene提供了几种环境下使用的Analyzer：SimpleAnalyzer、StandardAnalyzer、GermanAnalyzer等，其中StandardAnalyzer是经常使用的，因为它提供了对于中文的支持，在表建好后我们就需要往里面插入用于索引的记录，在Lucene中这个称为Document，有点类似数据库中table的一行记录，记录中的字段的添加方法，在Lucene中称为Field，这个和数据库中基本一样，对于Field Lucene分为可被索引的，可切分的，不可被切分的，不可被索引的几种组合类型，通过这几个元素基本上就可以建立起索引了。在查询时经常碰到的为另外几个概念，首先是Query，Lucene提供了几种经常可以用到的Query：TermQuery、MultiTermQuery、BooleanQuery、WildcardQuery、PhraseQuery、PrefixQuery、PhrasePrefixQuery、FuzzyQuery、RangeQuery、SpanQuery，Query其实也就是指对于需要查询的字段采用什么样的方式进行查询，如模糊查询、语义查询、短语查询、范围查询、组合查询等，还有就是QueryParser，QueryParser可用于创建不同的Query，还有一个MultiFieldQueryParser支持对于多个字段进行同一关键字的查询，IndexSearcher概念指的为需要对何目录下的索引文件进行何种方式的分析的查询，有点象对数据库的哪种索引表进行查询并按一定方式进行记录中字段的分解查询的概念，通过IndexSearcher以及Query即可查询出需要的结果，Lucene返回的为Hits.通过遍历Hits可获取返回的结果的Document，通过Document则可获取Field中的相关信息了。</p>
				<p>通过对于上面在建立索引和全文检索的基本概念的介绍希望能让你对Lucene建立一定的了解。</p>
				<p>3.2.       全文检索需求的实现</p>
				<p>索引建立部分的代码：</p>
				<p>
						<br />private void createIndex(String indexFilePath) throws Exception{</p>
				<p>        IndexWriter iwriter=getWriter(indexFilePath);</p>
				<p>        Document doc=new Document();</p>
				<p>        doc.add(Field.Keyword("name","jerry"));</p>
				<p>        doc.add(Field.Text("sender","<a href="mailto:bluedavy@gmail.com">bluedavy@gmail.com</a>"));</p>
				<p>        doc.add(Field.Text("receiver","<a href="mailto:google@gmail.com">google@gmail.com</a>"));</p>
				<p>        doc.add(Field.Text("title","用于索引的标题"));</p>
				<p>        doc.add(Field.UnIndexed("content","不建立索引的内容"));</p>
				<p>        Document doc2=new Document();</p>
				<p>        doc2.add(Field.Keyword("name","jerry.lin"));</p>
				<p>        doc2.add(Field.Text("sender","<a href="mailto:bluedavy@hotmail.com">bluedavy@hotmail.com</a>"));</p>
				<p>        doc2.add(Field.Text("receiver","<a href="mailto:msn@hotmail.com">msn@hotmail.com</a>"));</p>
				<p>        doc2.add(Field.Text("title","用于索引的第二个标题"));</p>
				<p>        doc2.add(Field.Text("content","建立索引的内容"));</p>
				<p>        iwriter.addDocument(doc);</p>
				<p>        iwriter.addDocument(doc2);</p>
				<p>        iwriter.optimize();</p>
				<p>        iwriter.close();</p>
				<p>    }</p>
				<p>    </p>
				<p>    private IndexWriter getWriter(String indexFilePath) throws Exception{</p>
				<p>        boolean append=true;</p>
				<p>        File file=new File(indexFilePath+File.separator+"segments");</p>
				<p>        if(file.exists())</p>
				<p>            append=false; </p>
				<p>        return new IndexWriter(indexFilePath,analyzer,append);</p>
				<p>    }</p>
				<p>
						<br />3.2.1.       对于某字段的关键字的模糊查询</p>
				<p>
						<br />Query query=new WildcardQuery(new Term("sender","*davy*"));</p>
				<p>        </p>
				<p>        Searcher searcher=new IndexSearcher(indexFilePath);</p>
				<p>        Hits hits=searcher.search(query);</p>
				<p>        for (int i = 0; i &lt; hits.length(); i++) {</p>
				<p>            System.out.println(hits.doc(i).get("name"));</p>
				<p>        }</p>
				<p>
						<br />3.2.2.       对于某字段的关键字的语义查询</p>
				<p>
						<br />Query query=QueryParser.parse("索引","title",analyzer);</p>
				<p>        </p>
				<p>        Searcher searcher=new IndexSearcher(indexFilePath);</p>
				<p>        Hits hits=searcher.search(query);</p>
				<p>        for (int i = 0; i &lt; hits.length(); i++) {</p>
				<p>            System.out.println(hits.doc(i).get("name"));</p>
				<p>        }</p>
				<p>
						<br />3.2.3.       对于多字段的关键字的查询</p>
				<p>
						<br />Query query=MultiFieldQueryParser.parse("索引",new String[]{"title","content"},analyzer);</p>
				<p>        </p>
				<p>        Searcher searcher=new IndexSearcher(indexFilePath);</p>
				<p>        Hits hits=searcher.search(query);</p>
				<p>        for (int i = 0; i &lt; hits.length(); i++) {</p>
				<p>            System.out.println(hits.doc(i).get("name"));</p>
				<p>        }</p>
				<p>
						<br />3.2.4.       复合查询(多种查询条件的综合查询)</p>
				<p>
						<br />Query query=MultiFieldQueryParser.parse("索引",new String[]{"title","content"},analyzer);</p>
				<p>        Query mquery=new WildcardQuery(new Term("sender","bluedavy*"));</p>
				<p>        TermQuery tquery=new TermQuery(new Term("name","jerry"));</p>
				<p>        </p>
				<p>        BooleanQuery bquery=new BooleanQuery();</p>
				<p>        bquery.add(query,true,false);</p>
				<p>        bquery.add(mquery,true,false);</p>
				<p>        bquery.add(tquery,true,false);</p>
				<p>        </p>
				<p>        Searcher searcher=new IndexSearcher(indexFilePath);</p>
				<p>        Hits hits=searcher.search(bquery);</p>
				<p>        for (int i = 0; i &lt; hits.length(); i++) {</p>
				<p>            System.out.println(hits.doc(i).get("name"));</p>
				<p>        }</p>
				<p>
						<br />四.  总结</p>
				<p>相信大家通过上面的说明能知道Lucene的一个基本的使用方法，在全文检索时建议大家先采用语义时的搜索，先搜索出有意义的内容，之后再进行模糊之类的搜索，^_^，这个还是需要根据搜索的需求才能定了，Lucene还提供了很多其他更好用的方法，这个就等待大家在使用的过程中自己去进一步的摸索了，比如对于Lucene本身提供的Query的更熟练的掌握，对于Filter、Sorter的使用，自己扩展实现Analyzer，自己实现Query等等，甚至可以去了解一些关于搜索引擎的技术(切词、索引排序 etc)等等。<br /></p>
				<center>
				</center>
		</div>
<img src ="http://www.blogjava.net/baoyaer/aggbug/99661.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/baoyaer/" target="_blank">大田斗</a> 2007-02-13 11:50 <a href="http://www.blogjava.net/baoyaer/articles/99661.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lucene In Action ch 4 笔记(I)--Analysis</title><link>http://www.blogjava.net/baoyaer/articles/99658.html</link><dc:creator>大田斗</dc:creator><author>大田斗</author><pubDate>Tue, 13 Feb 2007 03:32:00 GMT</pubDate><guid>http://www.blogjava.net/baoyaer/articles/99658.html</guid><wfw:comment>http://www.blogjava.net/baoyaer/comments/99658.html</wfw:comment><comments>http://www.blogjava.net/baoyaer/articles/99658.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/baoyaer/comments/commentRss/99658.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/baoyaer/services/trackbacks/99658.html</trackback:ping><description><![CDATA[ 
<p align="left">本章详细的讨论了 Lucene的分析处理过程和几个Analyzer. </p><p align="left">在indexing过程中 要把需要indexing的text分析处理一下, 经过处理和切词 然后建立index. 而不通的Analyzer有不同的分析规则, 因此在程序中使用Lucene时 选择正确的Analyzer是很重要的.</p><p align="left">1.Using Analyzers</p><p align="left">在使用Analyzer以前 先来看看text经过Analyzer分析后的效果吧:</p><p align="left">Listing 4.1 Visualizing analyzer effects<br />Analyzing "The quick brown fox jumped over the lazy dogs"<br />  WhitespaceAnalyzer:<br />    [The] [quick] [brown] [fox] [jumped] [over] [the] [lazy] [dogs]<br />  SimpleAnalyzer:<br />    [the] [quick] [brown] [fox] [jumped] [over] [the] [lazy] [dogs]<br />  StopAnalyzer:<br />    [quick] [brown] [fox] [jumped] [over] [lazy] [dogs]<br />  StandardAnalyzer:<br />    [quick] [brown] [fox] [jumped] [over] [lazy] [dogs]<br />　</p><p align="left">Analyzing "<a href="mailto:XY&amp;Z%20Corporation%20-%20xyz@example.com">XY&amp;Z Corporation - xyz@example.com</a>"<br />  WhitespaceAnalyzer:<br />    [XY&amp;Z] [Corporation] [-] <a href="mailto:[xyz@example.com">[xyz@example.com</a>]<br />  SimpleAnalyzer:<br />    [xy] [z] [corporation] [xyz] [example] [com]<br />  StopAnalyzer:<br />    [xy] [z] [corporation] [xyz] [example] [com]<br />  StandardAnalyzer:<br />    [xy&amp;z] [corporation] [xyz@example.com]</p><p align="left">上面是在下面我们要提到的一个例子的运行结果. 可以看出不同的Analyzer 是如何来分析text的.在分析The quick brown fox jumped over the lazy dogs 时, WhitespaceAnalyzer和 SimpleAnalyzer只是简单的把词分开,建立Term就可以了;而另外两个Analyzer则去掉了stop word. 而在分析XY&amp;Z Corporation - xyz@example.com 的时候 不同的Analyzer 对待 &amp; 和 - 的方式也是不一样的 . 现在对Analysis有个感性的了解,下面来看看不同处理阶段的分析过程.</p><p align="left">I. Indexing Analysis</p><p align="left">还记得在ch2 indexing 中 讲到 ,在建立index时,使用IndexWriter 在构造IndexWriter时,要使用到Analyser.如下所示:</p><font face="Courier" size="1"><p align="left">Analyzer analyzer = new StandardAnalyzer();</p><p align="left">IndexWriter writer = new IndexWriter(directory, </p></font><b><font face="宋体, MS Song">analyzer</font></b><font face="Courier" size="1">, true);<p></p></font><font face="Courier"> <p align="left">然后就可以使用writer对 document 来indexing了.如下</p><p></p></font><font face="Courier" size="1"> <p align="left">Document doc = new Document();</p><p align="left">doc.add(</p></font><font face="宋体, MS Song" size="1"><b>Field.Text</b></font><font face="Courier" size="1">("title", "This is the title"));<p align="left">doc.add(</p></font><font face="宋体, MS Song" size="1"><b>Field.UnStored</b></font><font face="Courier" size="1">("contents", "...document contents..."));<p align="left">writer.addDocument(doc);</p><p></p></font><font face="Courier"> <p align="left">使用的是在构造IndexWriter时 指定的Analyzer. 如果要给一个文档单独指定一个Analyzer 可以用下面的一个方法:</p><p align="left"> writer.addDocument(doc,analyzer);</p><p align="left">II.QueryParser Analysis</p><p align="left">  Analysis 是term搜索的关键.要确保经过Analyzer分析后的term和被索引的一样 这样才可以得到搜索结果.在使用QueryParser parse 用户输入的搜索表达式时可以 指定一个Analyzer 如下所示:</p><font face="Courier" size="1"><p align="left">Query query = QueryParser.parse(expression, "contents", </p></font><font face="Courier-Bold"><b>analyzer</b></font><font face="Courier" size="1">);<p></p></font><font face="NewBaskervilleITCbyBT-Roman" size="3"> <p align="left">通过QueryParser的静态方法实现. 如果使用QueryParser实例, 则可以在构造QueryParser时候 提供一个Analyzer 如下:</p></font><font face="Courier" size="1"><p align="left">QueryParser parser = new QueryParser("contents", </p></font><font face="Courier-Bold" size="1"><b>analyzer</b></font><font face="Courier" size="1">);<p align="left">query = parser.parse(expression);</p><p></p></font><font face="Courier" size="2"> <p align="left">QueryParser </p></font><font face="NewBaskervilleITCbyBT-Roman" size="3">analyzes individual pieces of the expression, not the expression as a<p align="left">whole, which may include operators, parenthesis, and other special expression</p><p align="left">syntax to denote range, wildcard, and fuzzy searches.</p><p align="left">QueryParser 平等的分析所有的text,她并不知道他们是如何每indxed, 这时如果当搜索一个被索引为Keyword的filed时 就可能会遇到问题.</p><p align="left">还有一个问题就是在分析一些包含其他元素的text时该如何处理 ,如 Html xml 文档, 他们都带有元素标签 而这些标签一般是不索引的.以及如何处理分域(field)索引, 如 Html 有Header 和 Body域 如何分开搜索 这个问题Analyzer现在也不能解决的, 因为在每次Analyzer都处理单个域. 在后面我们在进一步讨论该问题.</p><p></p></font></font> <p align="left">2. Analyzing the Analyzer</p><p align="left">要详细了解Lucene分析文本的过程就要知道Analyzer是如何工作的,下面就来看看Analyzer是怎么工作的吧. Analyzer是各个XXXAnalyzer的基类 ,该类出奇的简单(比我想象的要简单多了) 只要一个方法 tokenStream(String fieldName, Reader reader); fieldName 参数对有些Analyzer实现是没有作用的,如SimpleAnalyzer, 该类的代码如下:</p><font face="Courier" size="1"><p align="left">public final class SimpleAnalyzer extends Analyzer {</p><p align="left">  public TokenStream tokenStream(String fieldName, Reader reader) {</p><p align="left">    return new LowerCaseTokenizer(reader);</p><p align="left">  }</p><p align="left">}</p><p></p></font><font face="宋体, MS Song">可以看到该类也是出奇的简单, 只用到了LowerCaseTokenizer; 但LowerCaseTokenizer是干什么的呢? 看看名字就可以猜个差不多啦 ,</font><p align="left">该类把Text 中非字母(nonletters)的字符去掉,并把所有Text转换为小写.</p><font face="NewBaskervilleITCbyBT-Roman" size="3"><p align="left">而返回的 </p></font><font face="Courier" size="2">TokenStream </font><font face="NewBaskervilleITCbyBT-Roman" size="3">是一个 enumerator-like class ,通过她可以得到连续的 </font><font face="Courier" size="2">Token</font><font face="NewBaskervilleITCbyBT-Roman" size="3">s,当到达末尾时候返回null.</font><p> </p><!--Content End--><img src ="http://www.blogjava.net/baoyaer/aggbug/99658.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/baoyaer/" target="_blank">大田斗</a> 2007-02-13 11:32 <a href="http://www.blogjava.net/baoyaer/articles/99658.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lucene In Action ch 3 笔记--Add search</title><link>http://www.blogjava.net/baoyaer/articles/99657.html</link><dc:creator>大田斗</dc:creator><author>大田斗</author><pubDate>Tue, 13 Feb 2007 03:31:00 GMT</pubDate><guid>http://www.blogjava.net/baoyaer/articles/99657.html</guid><wfw:comment>http://www.blogjava.net/baoyaer/comments/99657.html</wfw:comment><comments>http://www.blogjava.net/baoyaer/articles/99657.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/baoyaer/comments/commentRss/99657.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/baoyaer/services/trackbacks/99657.html</trackback:ping><description><![CDATA[ 
<p align="left">今天看看 ch3, Add search to your Application. 真正开始使用 Lucene search 来搜索你的目标了.</p><p align="left">1. 实现一个简单的search feature</p><p align="left">   在本章中只限于讨论简单Lucene 搜索API, 有下面几个相关的类:</p><p align="left"> Lucene 基本搜索API:</p><table id="table1" width="100%" border="0"><tbody><tr><td><p align="center">类</p></td><td><p align="center">功能</p></td></tr><tr><td>IndexSearcher</td><td>搜索一个index的入口.所有的searches都是通过IndexSearcher 实例的几个重载的方法实现的.</td></tr><tr><td>Query (and subclasses)</td><td>各个子类封装了特定搜索类型的逻辑(logic),Query实例传递给IndexSearcher的search方法.</td></tr><tr><td>QueryParser </td><td>处理一个可读的表达式,转换为一个具体的Query实例.</td></tr><tr><td>Hits </td><td>包含了搜索的结果.有IndexSearcher的search函数返回.</td></tr></tbody></table><p>下面我们来看几个书中的例子:</p><p><code style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New', Courier"><font color="#000000">LiaTestCase.java  一个继承自TestCase 并且扩展了TestCase的类, 下面的几个例子都继承自该类.</font></code></p><p><code style="FONT-SIZE: 10pt; MARGIN: 0px; FONT-FAMILY: 'Courier New', Courier"><font color="#808080">01</font> <font color="#7f0055"><b>package </b></font><font color="#000000">lia.common;</font><br /><font color="#808080">02</font> <br /><font color="#808080">03</font> <font color="#7f0055"><b>import </b></font><font color="#000000">junit.framework.TestCase;</font><br /><font color="#808080">04</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.store.FSDirectory;</font><br /><font color="#808080">05</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.store.Directory;</font><br /><font color="#808080">06</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.search.Hits;</font><br /><font color="#808080">07</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.document.Document;</font><br /><font color="#808080">08</font> <br /><font color="#808080">09</font> <font color="#7f0055"><b>import </b></font><font color="#000000">java.io.IOException;</font><br /><font color="#808080">10</font> <font color="#7f0055"><b>import </b></font><font color="#000000">java.util.Date;</font><br /><font color="#808080">11</font> <font color="#7f0055"><b>import </b></font><font color="#000000">java.text.ParseException;</font><br /><font color="#808080">12</font> <font color="#7f0055"><b>import </b></font><font color="#000000">java.text.SimpleDateFormat;</font><br /><font color="#808080">13</font> <br /><font color="#808080">14</font> <font color="#3f5fbf">/**</font><br /><font color="#808080">15</font> <font color="#ffffff"> </font><font color="#3f5fbf">* LIA base class for test cases.</font><br /><font color="#808080">16</font> <font color="#ffffff"> </font><font color="#3f5fbf">*/</font><br /><font color="#808080">17</font> <font color="#7f0055"><b>public abstract class </b></font><font color="#000000">LiaTestCase </font><font color="#7f0055"><b>extends </b></font><font color="#000000">TestCase {</font><br /><font color="#808080">18</font> <font color="#ffffff">  </font><font color="#7f0055"><b>private </b></font><font color="#000000">String indexDir = System.getProperty(</font><font color="#2a00ff">"index.dir"</font><font color="#000000">);  // 测试 index 已经建立好了</font><br /><font color="#808080">19</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected </b></font><font color="#000000">Directory directory;</font><br /><font color="#808080">20</font> <br /><font color="#808080">21</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected void </b></font><font color="#000000">setUp() </font><font color="#7f0055"><b>throws </b></font><font color="#000000">Exception {</font><br /><font color="#808080">22</font> <font color="#ffffff">    </font><font color="#000000">directory = FSDirectory.getDirectory(indexDir, </font><font color="#7f0055"><b>false</b></font><font color="#000000">);</font><br /><font color="#808080">23</font> <font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#808080">24</font> <br /><font color="#808080">25</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected void </b></font><font color="#000000">tearDown() </font><font color="#7f0055"><b>throws </b></font><font color="#000000">Exception {</font><br /><font color="#808080">26</font> <font color="#ffffff">    </font><font color="#000000">directory.close();</font><br /><font color="#808080">27</font> <font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#808080">28</font> <br /><font color="#808080">29</font> <font color="#ffffff">  </font><font color="#3f5fbf">/**</font><br /><font color="#808080">30</font> <font color="#ffffff">   </font><font color="#3f5fbf">* For troubleshooting 为了 解决问题的方法</font><br /><font color="#808080">31</font> <font color="#ffffff">   </font><font color="#3f5fbf">*/</font><br /><font color="#808080">32</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected final void </b></font><font color="#000000">dumpHits(Hits hits) </font><font color="#7f0055"><b>throws </b></font><font color="#000000">IOException {</font><br /><font color="#808080">33</font> <font color="#ffffff">    </font><font color="#7f0055"><b>if </b></font><font color="#000000">(hits.length() == </font><font color="#990000">0</font><font color="#000000">) {</font><br /><font color="#808080">34</font> <font color="#ffffff">      </font><font color="#000000">System.out.println(</font><font color="#2a00ff">"No hits"</font><font color="#000000">);</font><br /><font color="#808080">35</font> <font color="#ffffff">    </font><font color="#000000">}</font><br /><font color="#808080">36</font> <br /><font color="#808080">37</font> <font color="#ffffff">    </font><font color="#7f0055"><b>for </b></font><font color="#000000">(</font><font color="#7f0055"><b>int </b></font><font color="#000000">i=</font><font color="#990000">0</font><font color="#000000">; i &lt; hits.length(); i++) {</font><br /><font color="#808080">38</font> <font color="#ffffff">      </font><font color="#000000">Document doc = hits.doc(i);</font><br /><font color="#808080">39</font> <font color="#ffffff">      </font><font color="#000000">System.out.println(hits.score(i) + </font><font color="#2a00ff">":" </font><font color="#000000">+ doc.get(</font><font color="#2a00ff">"title"</font><font color="#000000">));</font><br /><font color="#808080">40</font> <font color="#ffffff">    </font><font color="#000000">}</font><br /><font color="#808080">41</font> <font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#808080">42</font> <br /><font color="#808080">43</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected final void </b></font><font color="#000000">assertHitsIncludeTitle(</font><br /><font color="#808080">44</font> <font color="#ffffff">                                          </font><font color="#000000">Hits hits, String title)</font><br /><font color="#808080">45</font> <font color="#ffffff">    </font><font color="#7f0055"><b>throws </b></font><font color="#000000">IOException {</font><br /><font color="#808080">46</font> <font color="#ffffff">    </font><font color="#7f0055"><b>for </b></font><font color="#000000">(</font><font color="#7f0055"><b>int </b></font><font color="#000000">i=</font><font color="#990000">0</font><font color="#000000">; i &lt; hits.length(); i++) {</font><br /><font color="#808080">47</font> <font color="#ffffff">      </font><font color="#000000">Document doc = hits.doc(i);</font><br /><font color="#808080">48</font> <font color="#ffffff">      </font><font color="#7f0055"><b>if </b></font><font color="#000000">(title.equals(doc.get(</font><font color="#2a00ff">"title"</font><font color="#000000">))) {</font><br /><font color="#808080">49</font> <font color="#ffffff">        </font><font color="#000000">assertTrue(</font><font color="#7f0055"><b>true</b></font><font color="#000000">);</font><br /><font color="#808080">50</font> <font color="#ffffff">        </font><font color="#7f0055"><b>return</b></font><font color="#000000">;</font><br /><font color="#808080">51</font> <font color="#ffffff">      </font><font color="#000000">}</font><br /><font color="#808080">52</font> <font color="#ffffff">    </font><font color="#000000">}</font><br /><font color="#808080">53</font> <br /><font color="#808080">54</font> <font color="#ffffff">    </font><font color="#000000">fail(</font><font color="#2a00ff">"title '" </font><font color="#000000">+ title + </font><font color="#2a00ff">"' not found"</font><font color="#000000">);</font><br /><font color="#808080">55</font> <font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#808080">56</font> <br /><font color="#808080">57</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected final </b></font><font color="#000000">Date parseDate(String s) </font><font color="#7f0055"><b>throws </b></font><font color="#000000">ParseException {</font><br /><font color="#808080">58</font> <font color="#ffffff">      </font><font color="#7f0055"><b>return new </b></font><font color="#000000">SimpleDateFormat(</font><font color="#2a00ff">"yyyy-MM-dd"</font><font color="#000000">).parse(s);</font><br /><font color="#808080">59</font> <font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#808080">60</font> <font color="#000000">}</font></code></p><p>  I.搜索一个特定的Term 和利用QueryParser 解析用户输入的表达式</p><p>  要利用一个特定的term搜索,使用QueryTerm就可以了,单个term 尤其适合Keyword搜索. 解析用户输入的表达式可以更适合用户的使用方式,搜索表达式的解析有QueryParser来完成.如果表达式解析错误 会有异常抛出, 可以取得相信的错误信息 以便给用户适当的提示.在解析表达式时,还需要一个Analyzer 来分析用户的输入, 并根据不同的Analyzer来生产相应的Term然后构成Query实例.</p><p>下面看个例子吧:<font color="#000000"><code style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New', Courier">BasicSearchingTest.java</code></font></p><p><code style="FONT-SIZE: 10pt; MARGIN: 0px; FONT-FAMILY: 'Courier New', Courier"><font color="#808080">01</font> <font color="#7f0055"><b>package </b></font><font color="#000000">lia.searching;</font><br /><font color="#808080">02</font> <br /><font color="#808080">03</font> <font color="#7f0055"><b>import </b></font><font color="#000000">lia.common.LiaTestCase;</font><br /><font color="#808080">04</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.analysis.SimpleAnalyzer;</font><br /><font color="#808080">05</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.document.Document;</font><br /><font color="#808080">06</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.index.Term;</font><br /><font color="#808080">07</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.queryParser.QueryParser;</font><br /><font color="#808080">08</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.search.Hits;</font><br /><font color="#808080">09</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.search.IndexSearcher;</font><br /><font color="#808080">10</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.search.Query;</font><br /><font color="#808080">11</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.search.TermQuery;</font><br /><font color="#808080">12</font> <br /><font color="#808080">13</font> <font color="#7f0055"><b>public class </b></font><font color="#000000">BasicSearchingTest </font><font color="#7f0055"><b>extends </b></font><font color="#000000">LiaTestCase {</font><br /><font color="#808080">14</font> <br /><font color="#808080">15</font> <font color="#ffffff">  </font><font color="#7f0055"><b>public void </b></font><font color="#000000">testTerm() </font><font color="#7f0055"><b>throws </b></font><font color="#000000">Exception {</font><br /><font color="#808080">16</font> <font color="#ffffff">    </font><font color="#000000">IndexSearcher searcher = </font><font color="#7f0055"><b>new </b></font><font color="#000000">IndexSearcher(directory);</font><br /><font color="#808080">17</font> <font color="#ffffff">    </font><font color="#000000">Term t = </font><font color="#7f0055"><b>new </b></font><font color="#000000">Term(</font><font color="#2a00ff">"subject"</font><font color="#000000">, </font><font color="#2a00ff">"ant"</font><font color="#000000">);                </font><font color="#ff0000">// 构造一个Term</font><br /><font color="#808080">18</font> <font color="#ffffff">    </font><font color="#000000">Query query = </font><font color="#7f0055"><b>new </b></font><font color="#000000">TermQuery(t);</font><br /><font color="#808080">19</font> <font color="#ffffff">    </font><font color="#000000">Hits hits = searcher.search(query);                 // 搜索</font><br /><font color="#808080">20</font> <font color="#ffffff">    </font><font color="#000000">assertEquals(</font><font color="#2a00ff">"JDwA"</font><font color="#000000">, </font><font color="#990000">1</font><font color="#000000">, hits.length());             //测试结果</font><br /><font color="#808080">21</font> <br /><font color="#808080">22</font> <font color="#ffffff">    </font><font color="#000000">t = </font><font color="#7f0055"><b>new </b></font><font color="#000000">Term(</font><font color="#2a00ff">"subject"</font><font color="#000000">, </font><font color="#2a00ff">"junit"</font><font color="#000000">);</font><br /><font color="#808080">23</font> <font color="#ffffff">    </font><font color="#000000">hits = searcher.search(</font><font color="#7f0055"><b>new </b></font><font color="#000000">TermQuery(t));                   </font><br /><font color="#808080">24</font> <font color="#ffffff">    </font><font color="#000000">assertEquals(</font><font color="#990000">2</font><font color="#000000">, hits.length());</font><br /><font color="#808080">25</font> <br /><font color="#808080">26</font> <font color="#ffffff">    </font><font color="#000000">searcher.close();</font><br /><font color="#808080">27</font> <font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#808080">28</font> <br /><font color="#808080">29</font> <font color="#ffffff">  </font><font color="#7f0055"><b>public void </b></font><font color="#000000">testKeyword() </font><font color="#7f0055"><b>throws </b></font><font color="#000000">Exception {  // 测试关键字搜索</font><br /><font color="#808080">30</font> <font color="#ffffff">    </font><font color="#000000">IndexSearcher searcher = </font><font color="#7f0055"><b>new </b></font><font color="#000000">IndexSearcher(directory);</font><br /><font color="#808080">31</font> <font color="#ffffff">    </font><font color="#000000">Term t = </font><font color="#7f0055"><b>new </b></font><font color="#000000">Term(</font><font color="#2a00ff">"isbn"</font><font color="#000000">, </font><font color="#2a00ff">"1930110995"</font><font color="#000000">);                 // 关键字 term</font><br /><font color="#808080">32</font> <font color="#ffffff">    </font><font color="#000000">Query query = </font><font color="#7f0055"><b>new </b></font><font color="#000000">TermQuery(t);</font><br /><font color="#808080">33</font> <font color="#ffffff">    </font><font color="#000000">Hits hits = searcher.search(query);</font><br /><font color="#808080">34</font> <font color="#ffffff">    </font><font color="#000000">assertEquals(</font><font color="#2a00ff">"JUnit in Action"</font><font color="#000000">, </font><font color="#990000">1</font><font color="#000000">, hits.length());</font><br /><font color="#808080">35</font> <font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#808080">36</font> <br /><font color="#808080">37</font> <font color="#ffffff">  </font><font color="#7f0055"><b>public void </b></font><font color="#000000">testQueryParser() </font><font color="#7f0055"><b>throws </b></font><font color="#000000">Exception {  // 测试 QueryParser.</font><br /><font color="#808080">38</font> <font color="#ffffff">    </font><font color="#000000">IndexSearcher searcher = </font><font color="#7f0055"><b>new </b></font><font color="#000000">IndexSearcher(directory);</font><br /><font color="#808080">39</font> <br /><font color="#808080">40</font> <font color="#ffffff">    </font><font color="#000000">Query query = QueryParser.parse(</font><font color="#2a00ff">"+JUNIT +ANT -MOCK"</font><font color="#000000">,</font><br /><font color="#808080">41</font> <font color="#ffffff">                                    </font><font color="#2a00ff">"contents"</font><font color="#000000">,</font><br /><font color="#808080">42</font> <font color="#ffffff">                                    </font><font color="#7f0055"><b>new </b></font><font color="#000000">SimpleAnalyzer());  // 通过解析搜索表达式 返回一个Query实例</font><br /><font color="#808080">43</font> <font color="#ffffff">    </font><font color="#000000">Hits hits = searcher.search(query);</font><br /><font color="#808080">44</font> <font color="#ffffff">    </font><font color="#000000">assertEquals(</font><font color="#990000">1</font><font color="#000000">, hits.length());</font><br /><font color="#808080">45</font> <font color="#ffffff">    </font><font color="#000000">Document d = hits.doc(</font><font color="#990000">0</font><font color="#000000">);</font><br /><font color="#808080">46</font> <font color="#ffffff">    </font><font color="#000000">assertEquals(</font><font color="#2a00ff">"Java Development with Ant"</font><font color="#000000">, d.get(</font><font color="#2a00ff">"title"</font><font color="#000000">));</font><br /><font color="#808080">47</font> <br /><font color="#808080">48</font> <font color="#ffffff">    </font><font color="#000000">query = QueryParser.parse(</font><font color="#2a00ff">"mock OR junit"</font><font color="#000000">,</font><br /><font color="#808080">49</font> <font color="#ffffff">                              </font><font color="#2a00ff">"contents"</font><font color="#000000">,</font><br /><font color="#808080">50</font> <font color="#ffffff">                              </font><font color="#7f0055"><b>new </b></font><font color="#000000">SimpleAnalyzer());              </font></code><code style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New', Courier"><font color="#000000">// 通过解析搜索表达式 返回一个Query实例</font></code><code style="FONT-SIZE: 10pt; MARGIN: 0px; FONT-FAMILY: 'Courier New', Courier"><br /><font color="#808080">51</font> <font color="#ffffff">    </font><font color="#000000">hits = searcher.search(query);</font><br /><font color="#808080">52</font> <font color="#ffffff">    </font><font color="#000000">assertEquals(</font><font color="#2a00ff">"JDwA and JIA"</font><font color="#000000">, </font><font color="#990000">2</font><font color="#000000">, hits.length());</font><br /><font color="#808080">53</font> <font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#808080">54</font> <font color="#000000">}</font></code></p><img src ="http://www.blogjava.net/baoyaer/aggbug/99657.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/baoyaer/" target="_blank">大田斗</a> 2007-02-13 11:31 <a href="http://www.blogjava.net/baoyaer/articles/99657.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lucene In Action ch 2 笔记--indexing详解 </title><link>http://www.blogjava.net/baoyaer/articles/99655.html</link><dc:creator>大田斗</dc:creator><author>大田斗</author><pubDate>Tue, 13 Feb 2007 03:29:00 GMT</pubDate><guid>http://www.blogjava.net/baoyaer/articles/99655.html</guid><wfw:comment>http://www.blogjava.net/baoyaer/comments/99655.html</wfw:comment><comments>http://www.blogjava.net/baoyaer/articles/99655.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/baoyaer/comments/commentRss/99655.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/baoyaer/services/trackbacks/99655.html</trackback:ping><description><![CDATA[ 
<p align="left">Lucene In Action ch2 系统的讲解了 indexing,下面就来看看吧.</p><p align="left">1,indexing的处理过程.</p><p align="left">  首先要把indexing的数据转换为text,因为Lucene只能索引text,然后由Analysis来过虑text,把一些ch1中提到的所谓的stop words 过滤掉, 然后建立index.建立的index为<font face="NewBaskervilleITCbyBT-Italic" size="3"><i>inverted index </i>也就是所谓的<i>倒排索引.</i></font></p><p align="left"><font face="NewBaskervilleITCbyBT-Italic">2,基本的ingex操作</font></p><p align="left"><font face="NewBaskervilleITCbyBT-Italic">   基本的操作 包括 :添加 删除 更新. </font></p><p align="left"><font face="NewBaskervilleITCbyBT-Italic">I . 添加</font></p><p align="left"><font face="NewBaskervilleITCbyBT-Italic">下面我们看个例子代码 </font><code style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New', Courier"><font color="#000000">BaseIndexingTestCase.class</font></code></p><p></p><table id="table1" cellspacing="0" cellpadding="3" bgcolor="#eff3e7" border="2"><tbody><tr><td valign="top" nowrap="" align="left"><code style="FONT-SIZE: 10pt; MARGIN: 0px; FONT-FAMILY: 'Courier New', Courier"><font color="#808080">01</font> <font color="#7f0055"><b>package </b></font><font color="#000000">lia.indexing;</font><br /><font color="#808080">02</font> <br /><font color="#808080">03</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.store.Directory;</font><br /><font color="#808080">04</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.store.FSDirectory;</font><br /><font color="#808080">05</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.document.Document;</font><br /><font color="#808080">06</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.document.Field;</font><br /><font color="#808080">07</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.index.IndexWriter;</font><br /><font color="#808080">08</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.index.IndexReader;</font><br /><font color="#808080">09</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.analysis.Analyzer;</font><br /><font color="#808080">10</font> <font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.analysis.SimpleAnalyzer;</font><br /><font color="#808080">11</font> <br /><font color="#808080">12</font> <font color="#7f0055"><b>import </b></font><font color="#000000">junit.framework.TestCase;</font><br /><font color="#808080">13</font> <font color="#7f0055"><b>import </b></font><font color="#000000">java.io.IOException;</font><br /><font color="#808080">14</font> <br /><font color="#808080">15</font> <font color="#3f5fbf">/**</font><br /><font color="#808080">16</font> <font color="#ffffff"> </font><font color="#3f5fbf">*</font><br /><font color="#808080">17</font> <font color="#ffffff"> </font><font color="#3f5fbf">*/</font><br /><font color="#808080">18</font> <font color="#7f0055"><b>public abstract class </b></font><font color="#000000">BaseIndexingTestCase </font><font color="#7f0055"><b>extends </b></font><font color="#000000">TestCase {</font><br /><font color="#808080">19</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected </b></font><font color="#000000">String[] keywords = {</font><font color="#2a00ff">"1"</font><font color="#000000">, </font><font color="#2a00ff">"2"</font><font color="#000000">};</font><br /><font color="#808080">20</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected </b></font><font color="#000000">String[] unindexed = {</font><font color="#2a00ff">"Netherlands"</font><font color="#000000">, </font><font color="#2a00ff">"Italy"</font><font color="#000000">};</font><br /><font color="#808080">21</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected </b></font><font color="#000000">String[] unstored = {</font><font color="#2a00ff">"Amsterdam has lots of bridges"</font><font color="#000000">,</font><br /><font color="#808080">22</font> <font color="#ffffff">                                 </font><font color="#2a00ff">"Venice has lots of canals"</font><font color="#000000">};</font><br /><font color="#808080">23</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected </b></font><font color="#000000">String[] text = {</font><font color="#2a00ff">"Amsterdam"</font><font color="#000000">, </font><font color="#2a00ff">"Venice"</font><font color="#000000">};</font><br /><font color="#808080">24</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected </b></font><font color="#000000">Directory dir;</font><br /><font color="#808080">25</font>   // setUp 方法<br /><font color="#808080">26</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected void </b></font><font color="#000000">setUp() </font><font color="#7f0055"><b>throws </b></font><font color="#000000">IOException {</font><br /><font color="#808080">27</font> <font color="#ffffff">    </font><font color="#000000">String indexDir =</font><br /><font color="#808080">28</font> <font color="#ffffff">      </font><font color="#000000">System.getProperty(</font><font color="#2a00ff">"java.io.tmpdir"</font><font color="#000000">, </font><font color="#2a00ff">"tmp"</font><font color="#000000">) +</font><br /><font color="#808080">29</font> <font color="#ffffff">      </font><font color="#000000">System.getProperty(</font><font color="#2a00ff">"file.separator"</font><font color="#000000">) + </font><font color="#2a00ff">"index-dir"</font><font color="#000000">;</font><br /><font color="#808080">30</font> <font color="#ffffff">    </font><font color="#000000">dir = FSDirectory.getDirectory(indexDir, </font><font color="#7f0055"><b>true</b></font><font color="#000000">);</font><br /><font color="#808080">31</font> <font color="#ffffff">    </font><font color="#000000">addDocuments(dir);</font><br /><font color="#808080">32</font> <font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#808080">33</font> <br /><font color="#808080">34</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected void </b></font><font color="#000000">addDocuments(Directory dir)</font><br /><font color="#808080">35</font> <font color="#ffffff">    </font><font color="#7f0055"><b>throws </b></font><font color="#000000">IOException {</font><br /><font color="#808080">36</font> <font color="#ffffff">    </font><font color="#000000">IndexWriter writer = </font><font color="#7f0055"><b>new </b></font><font color="#000000">IndexWriter(dir, getAnalyzer(),</font><br /><font color="#808080">37</font> <font color="#ffffff">      </font><font color="#7f0055"><b>true</b></font><font color="#000000">);    // 得到indexWriter 实例</font><br /><font color="#808080">38</font> <font color="#ffffff">    </font><font color="#000000">writer.setUseCompoundFile(isCompound());</font><br /><font color="#808080">39</font> <font color="#ffffff">    </font><font color="#7f0055"><b>for </b></font><font color="#000000">(</font><font color="#7f0055"><b>int </b></font><font color="#000000">i = </font><font color="#990000">0</font><font color="#000000">; i &lt; keywords.length; i++) {</font><br /><font color="#808080">40</font> <font color="#ffffff">      </font><font color="#000000">Document doc = </font><font color="#7f0055"><b>new </b></font><font color="#000000">Document();        // 添加文档</font><br /><font color="#808080">41</font> <font color="#ffffff">      </font><font color="#000000">doc.add(Field.Keyword(</font><font color="#2a00ff">"id"</font><font color="#000000">, keywords[i]));</font><br /><font color="#808080">42</font> <font color="#ffffff">      </font><font color="#000000">doc.add(Field.UnIndexed(</font><font color="#2a00ff">"country"</font><font color="#000000">, unindexed[i]));</font><br /><font color="#808080">43</font> <font color="#ffffff">      </font><font color="#000000">doc.add(Field.UnStored(</font><font color="#2a00ff">"contents"</font><font color="#000000">, unstored[i]));</font><br /><font color="#808080">44</font> <font color="#ffffff">      </font><font color="#000000">doc.add(Field.Text(</font><font color="#2a00ff">"city"</font><font color="#000000">, text[i]));</font><br /><font color="#808080">45</font> <font color="#ffffff">      </font><font color="#000000">writer.addDocument(doc);</font><br /><font color="#808080">46</font> <font color="#ffffff">    </font><font color="#000000">}</font><br /><font color="#808080">47</font> <font color="#ffffff">    </font><font color="#000000">writer.optimize();   // 优化index</font><br /><font color="#808080">48</font> <font color="#ffffff">    </font><font color="#000000">writer.close();</font><br /><font color="#808080">49</font> <font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#808080">50</font>   // 可以覆盖该方法提供不同的Analyzer <br /><font color="#808080">51</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected </b></font><font color="#000000">Analyzer getAnalyzer() {</font><br /><font color="#808080">52</font> <font color="#ffffff">    </font><font color="#7f0055"><b>return new </b></font><font color="#000000">SimpleAnalyzer();</font><br /><font color="#808080">53</font> <font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#808080">54</font>   // 也可以覆盖该方法 指出Compound属性 是否是 </code><font face="FranklinGothicITCbyBT-DemiItal" size="3"><i>Heterogeneous Documents</i></font><code style="FONT-SIZE: 10pt; MARGIN: 0px; FONT-FAMILY: 'Courier New', Courier"><br /><font color="#808080">55</font> <font color="#ffffff">  </font><font color="#7f0055"><b>protected boolean </b></font><font color="#000000">isCompound() {</font><br /><font color="#808080">56</font> <font color="#ffffff">    </font><font color="#7f0055"><b>return true</b></font><font color="#000000">;</font><br /><font color="#808080">57</font> <font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#808080">58</font>   // 测试添加文档<br /><font color="#808080">59</font> <font color="#ffffff">  </font><font color="#7f0055"><b>public void </b></font><font color="#000000">testIndexWriter() </font><font color="#7f0055"><b>throws </b></font><font color="#000000">IOException {</font><br /><font color="#808080">60</font> <font color="#ffffff">    </font><font color="#000000">IndexWriter writer = </font><font color="#7f0055"><b>new </b></font><font color="#000000">IndexWriter(dir, getAnalyzer(),</font><br /><font color="#808080">61</font> <font color="#ffffff">      </font><font color="#7f0055"><b>false</b></font><font color="#000000">);</font><br /><font color="#808080">62</font> <font color="#ffffff">    </font><font color="#000000">assertEquals(keywords.length, writer.docCount());</font><br /><font color="#808080">63</font> <font color="#ffffff">    </font><font color="#000000">writer.close();</font><br /><font color="#808080">64</font> <font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#808080">65</font>   // 测试IndexReader<br /><font color="#808080">66</font> <font color="#ffffff">  </font><font color="#7f0055"><b>public void </b></font><font color="#000000">testIndexReader() </font><font color="#7f0055"><b>throws </b></font><font color="#000000">IOException {</font><br /><font color="#808080">67</font> <font color="#ffffff">    </font><font color="#000000">IndexReader reader = IndexReader.open(dir);</font><br /><font color="#808080">68</font> <font color="#ffffff">    </font><font color="#000000">assertEquals(keywords.length, reader.maxDoc());</font><br /><font color="#808080">69</font> <font color="#ffffff">    </font><font color="#000000">assertEquals(keywords.length, reader.numDocs());</font><br /><font color="#808080">70</font> <font color="#ffffff">    </font><font color="#000000">reader.close();</font><br /><font color="#808080">71</font> <font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#808080">72</font> <font color="#000000">}</font></code></td><!-- end source code --></tr><!-- start Java2Html link --><!-- end Java2Html link --></tbody></table><p align="left"><font face="NewBaskervilleITCbyBT-Italic">这是一个测试超类 可以被其他的测试用例继承 来测试不同的功能.上面带有详细的注释.</font></p><p align="left"><font face="NewBaskervilleITCbyBT-Italic">在添加Field时, 会遇到同义词的情况,添加同义词由两种方式:</font></p><p align="left"><font face="NewBaskervilleITCbyBT-Italic"> a.创建一个同义词词组,循环添加到Single Strng的不同Field中.</font></p><p align="left"><font face="NewBaskervilleITCbyBT-Italic"> b.把同义词添加到一个Base word的field中.如下:</font></p><p><font face="Courier" size="1"></font><font face="NewBaskervilleITCbyBT-Roman" size="3"><font face="Courier" size="1"> </font></font></p><p align="left"><font color="#800000">String baseWord = "fast";</font></p><p align="left"><font color="#800000">String synonyms[] = String {"quick", "rapid", "speedy"};</font></p><p align="left"><font color="#800000">Document doc = new Document();</font></p><p align="left"><font color="#800000">doc.add(Field.Text("word", baseWord));</font></p><p align="left"><font color="#800000">for (int i = 0; i &lt; synonyms.length; i++) {</font></p><p align="left"><font color="#800000">doc.add(Field.Text("word", synonyms[i]));</font></p><p align="left"><font color="#800000">}</font></p><p><font face="Courier"> </font></p><p align="left"><font color="#800000">这样 在</font><font face="Courier" color="#800000">Lucene</font><font face="Courier">内部把每个词都添加的一个名为word的Field中,在搜索时 你可以使用任何一个给定的词语.</font></p><p></p><img src ="http://www.blogjava.net/baoyaer/aggbug/99655.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/baoyaer/" target="_blank">大田斗</a> 2007-02-13 11:29 <a href="http://www.blogjava.net/baoyaer/articles/99655.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lucene In Action ch 1 笔记 -- 基本概念</title><link>http://www.blogjava.net/baoyaer/articles/99653.html</link><dc:creator>大田斗</dc:creator><author>大田斗</author><pubDate>Tue, 13 Feb 2007 03:28:00 GMT</pubDate><guid>http://www.blogjava.net/baoyaer/articles/99653.html</guid><wfw:comment>http://www.blogjava.net/baoyaer/comments/99653.html</wfw:comment><comments>http://www.blogjava.net/baoyaer/articles/99653.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/baoyaer/comments/commentRss/99653.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/baoyaer/services/trackbacks/99653.html</trackback:ping><description><![CDATA[ 
<p align="left">在第一章中作者 主要讲了Lucene 是什么 能用来干什么, 以及一个 indexing 和 searching 的例子, 通过例子讲解了一点基本(核心)概念.给读者一个基本的Lucene 概况. 然后又介绍了现在流行的 搜索框架.</p><p align="left">我们主要来看看 这个 indexing and searching 例子 然后了解一些基本概念.</p><p align="left"><code style="FONT-SIZE: 10pt; MARGIN: 0px; FONT-FAMILY: 'Courier New', Courier"><font color="#7f0055"><b>package </b></font><font color="#000000">lia.meetlucene;</font><br /><br /><font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.index.IndexWriter;</font><br /><font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.analysis.standard.StandardAnalyzer;</font><br /><font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.document.Document;</font><br /><font color="#7f0055"><b>import </b></font><font color="#000000">org.apache.lucene.document.Field;</font><br /><br /><font color="#7f0055"><b>import </b></font><font color="#000000">java.io.File;</font><br /><font color="#7f0055"><b>import </b></font><font color="#000000">java.io.IOException;</font><br /><font color="#7f0055"><b>import </b></font><font color="#000000">java.io.FileReader;</font><br /><font color="#7f0055"><b>import </b></font><font color="#000000">java.util.Date;</font><br /><br /><font color="#3f5fbf">/**</font><br /><font color="#ffffff"> </font><font color="#3f5fbf">* This code was originally written for</font><br /><font color="#ffffff"> </font><font color="#3f5fbf">* Erik's Lucene intro java.net article</font><br /><font color="#ffffff"> </font><font color="#3f5fbf">*/</font><br /><font color="#7f0055"><b>public class </b></font><font color="#000000">Indexer {</font><br /><br /><font color="#ffffff">  </font><font color="#7f0055"><b>public static void </b></font><font color="#000000">main(String[] args) </font><font color="#7f0055"><b>throws </b></font><font color="#000000">Exception {</font><br /><font color="#ffffff">    </font><font color="#7f0055"><b>if </b></font><font color="#000000">(args.length != </font><font color="#990000">2</font><font color="#000000">) {</font><br /><font color="#ffffff">      </font><font color="#7f0055"><b>throw new </b></font><font color="#000000">Exception(</font><font color="#2a00ff">"Usage: java " </font><font color="#000000">+ Indexer.</font><font color="#7f0055"><b>class</b></font><font color="#000000">.getName()</font><br /><font color="#ffffff">        </font><font color="#000000">+ </font><font color="#2a00ff">" &lt;index dir&gt; &lt;data dir&gt;"</font><font color="#000000">);</font><br /><font color="#ffffff">    </font><font color="#000000">}</font><br /><font color="#ffffff">    </font><font color="#000000">File indexDir = </font><font color="#7f0055"><b>new </b></font><font color="#000000">File(args[</font><font color="#990000">0</font><font color="#000000">]); // 在该目录中创建Lucene Incex</font><br /><font color="#ffffff">    </font><font color="#000000">File dataDir = </font><font color="#7f0055"><b>new </b></font><font color="#000000">File(args[</font><font color="#990000">1</font><font color="#000000">]); // 该目录中存放备索引的文件</font><br /><br /><font color="#ffffff">    </font><font color="#7f0055"><b>long </b></font><font color="#000000">start = </font><font color="#7f0055"><b>new </b></font><font color="#000000">Date().getTime();</font><br /><font color="#ffffff">    </font><font color="#7f0055"><b>int </b></font><font color="#000000">numIndexed = index(indexDir, dataDir);</font><br /><font color="#ffffff">    </font><font color="#7f0055"><b>long </b></font><font color="#000000">end = </font><font color="#7f0055"><b>new </b></font><font color="#000000">Date().getTime();</font><br /><br /><font color="#ffffff">    </font><font color="#000000">System.out.println(</font><font color="#2a00ff">"Indexing " </font><font color="#000000">+ numIndexed + </font><font color="#2a00ff">" files took "</font><br /><font color="#ffffff">      </font><font color="#000000">+ (end - start) + </font><font color="#2a00ff">" milliseconds"</font><font color="#000000">);</font><br /><font color="#ffffff">  </font><font color="#000000">}</font><br /><br /><font color="#ffffff">  </font><font color="#7f0055"><b>public static int </b></font><font color="#000000">index(File indexDir, File dataDir)</font><br /><font color="#ffffff">    </font><font color="#7f0055"><b>throws </b></font><font color="#000000">IOException {</font><br /><br /><font color="#ffffff">    </font><font color="#7f0055"><b>if </b></font><font color="#000000">(!dataDir.exists() || !dataDir.isDirectory()) {</font><br /><font color="#ffffff">      </font><font color="#7f0055"><b>throw new </b></font><font color="#000000">IOException(dataDir</font><br /><font color="#ffffff">        </font><font color="#000000">+ </font><font color="#2a00ff">" does not exist or is not a directory"</font><font color="#000000">);</font><br /><font color="#ffffff">    </font><font color="#000000">}</font><br /><br /><font color="#ffffff">    </font><font color="#000000">IndexWriter writer = </font><font color="#7f0055"><b>new </b></font><font color="#000000">IndexWriter(indexDir,</font><br /><font color="#ffffff">      </font><font color="#7f0055"><b>new </b></font><font color="#000000">StandardAnalyzer(), </font><font color="#7f0055"><b>true</b></font><font color="#000000">);               //</font><font color="#ff0000">(1)</font><font color="#008000">创建 Lucene Index</font><br /><font color="#ffffff">    </font><font color="#000000">writer.setUseCompoundFile(</font><font color="#7f0055"><b>false</b></font><font color="#000000">);</font><br /><br /><font color="#ffffff">    </font><font color="#000000">indexDirectory(writer, dataDir);</font><br /><br /><font color="#ffffff">    </font><font color="#7f0055"><b>int </b></font><font color="#000000">numIndexed = writer.docCount();</font><br /><font color="#ffffff">    </font><font color="#000000">writer.optimize();</font><br /><font color="#ffffff">    </font><font color="#000000">writer.close();                               // close index</font><br /><font color="#ffffff">    </font><font color="#7f0055"><b>return </b></font><font color="#000000">numIndexed;</font><br /><font color="#ffffff">  </font><font color="#000000">}</font><br /><br /><font color="#ffffff">  </font><font color="#7f0055"><b>private static void </b></font><font color="#000000">indexDirectory(IndexWriter writer, File dir)</font><br /><font color="#ffffff">    </font><font color="#7f0055"><b>throws </b></font><font color="#000000">IOException {</font><br /><br /><font color="#ffffff">    </font><font color="#000000">File[] files = dir.listFiles();</font><br /><br /><font color="#ffffff">    </font><font color="#7f0055"><b>for </b></font><font color="#000000">(</font><font color="#7f0055"><b>int </b></font><font color="#000000">i = </font><font color="#990000">0</font><font color="#000000">; i &lt; files.length; i++) {</font><br /><font color="#ffffff">      </font><font color="#000000">File f = files[i];</font><br /><font color="#ffffff">      </font><font color="#7f0055"><b>if </b></font><font color="#000000">(f.isDirectory()) {</font><br /><font color="#ffffff">        </font><font color="#000000">indexDirectory(writer, f);  </font><font color="#3f7f5f">//</font><font color="#ff0000">(2)</font><font color="#3f7f5f"> recurse</font><br /><font color="#ffffff">      </font><font color="#000000">} </font><font color="#7f0055"><b>else if </b></font><font color="#000000">(f.getName().endsWith(</font><font color="#2a00ff">".txt"</font><font color="#000000">)) {</font><br /><font color="#ffffff">        </font><font color="#000000">indexFile(writer, f);</font><br /><font color="#ffffff">      </font><font color="#000000">}</font><br /><font color="#ffffff">    </font><font color="#000000">}</font><br /><font color="#ffffff">  </font><font color="#000000">}</font><br /><br /><font color="#ffffff">  </font><font color="#7f0055"><b>private static void </b></font><font color="#000000">indexFile(IndexWriter writer, File f)</font><br /><font color="#ffffff">    </font><font color="#7f0055"><b>throws </b></font><font color="#000000">IOException {</font><br /><br /><font color="#ffffff">    </font><font color="#7f0055"><b>if </b></font><font color="#000000">(f.isHidden() || !f.exists() || !f.canRead()) {</font><br /><font color="#ffffff">      </font><font color="#7f0055"><b>return</b></font><font color="#000000">;</font><br /><font color="#ffffff">    </font><font color="#000000">}</font><br /><br /><font color="#ffffff">    </font><font color="#000000">System.out.println(</font><font color="#2a00ff">"Indexing " </font><font color="#000000">+ f.getCanonicalPath());</font><br /><br /><font color="#ffffff">    </font><font color="#000000">Document doc = </font><font color="#7f0055"><b>new </b></font><font color="#000000">Document();</font><br /><font color="#ffffff">    </font><font color="#000000">doc.add(Field.Text(</font><font color="#2a00ff">"contents"</font><font color="#000000">, </font><font color="#7f0055"><b>new </b></font><font color="#000000">FileReader(f)));  // </font><font color="#ff0000">(3) </font><font color="#000000">index file content</font><br /><font color="#ffffff">    </font><font color="#000000">doc.add(Field.Keyword(</font><font color="#2a00ff">"filename"</font><font color="#000000">, f.getCanonicalPath())); // </font><font color="#ff0000">(4)</font><font color="#000000"> index file name</font><br /><font color="#ffffff">    </font><font color="#000000">writer.addDocument(doc);                   //</font><font color="#ff0000">(5)</font><font color="#000000"> add document in Lucene index</font><br /><font color="#ffffff">  </font><font color="#000000">}</font><br /><font color="#000000">}</font></code></p><p align="left">上面的Indexer 使用了几行 Lucene的API, 来indexing 一个目录下面的文件. 运行时候 需要两个参数 , 一个保存index的目录和要索引的文件目录.</p><p align="left">在上面的类中,需要下面的一些Lucene classes 来执行 indexing 处理:</p><font lang="ZH-CN" face="ZapfDingbats" size="1"><p align="left">■ </p></font><font face="Courier" size="2">IndexWriter</font><font lang="ZH-CN" face="ZapfDingbats" size="1"><p align="left">■ </p></font><font face="Courier" size="2">Directory</font><font lang="ZH-CN" face="ZapfDingbats" size="1"><p align="left">■ </p></font><font face="Courier" size="2">Analyzer</font><font lang="ZH-CN" face="ZapfDingbats" size="1"><p align="left">■ </p></font><font face="Courier" size="2">Document</font><font lang="ZH-CN" face="ZapfDingbats" size="1"><p align="left">■ </p></font><font face="Courier" size="2">Field</font><p align="left">IndexWriter 是indexing 处理时用到的中心组件,该类create 新index 并且添加documents 到已经存在的index, BTW,在Lucene中还有别的方法来更新index.</p><p align="left">Directory: 用来存放index文件的文件目录,该类是个抽象类,用几个子类可以使用,上面使用了File来代表文件路径,在Lucene中用两个主要的Directory子类,一个FSDirectory,一个 RAMDirectory,前者是把index保存到硬盘中的;后者是保存在内存中的,在内存中处理数度当然就相应的快一些 了但只适合于小文件.</p><p align="left">Analyzer: 在文件备索引以前要先通过Analyzer分析,去掉一些对search无用的词语(如英语中 的小词 in at a 等等,在Lucene中被称为stop words 的词),还可以处理大小写的问题(是大小写相关啊 还是不相关),使用Lucene时候 选择Analyzer是关键.</p><p align="left">Document: 代表一些Fields的集合.可以想象为一些数据的集合.</p><p align="left">Field: 在index中的每一个Document中都包含一些 命名的Fields 用Field来构造, 每一个field都是的搜索是符合要求和不符合要求的index中的一些数据,Lucene提供了四种不同的Field,</p><p align="left">1,Keyword  不分析 只索引和保存,象一些特殊信息 不可以分割的 如 电话号码 网站 Email 等.</p><p align="left">2,UnIndexed 既不索引也不分析,只是把值保存在index中.该类型适合用来显示搜索结果的field,但是你从来不搜索该显示的数据,如URL</p><p align="left">3,UnStored UnIndexed的对立面, 分析和索引但是不保存在index中,适合大型数据 只搜索但是不显示原始数据.</p><p align="left">4,Test 分析且索引,如果索引数据是String则也保存在index中, 如果是Reader则不保存.</p><!--Content End--><img src ="http://www.blogjava.net/baoyaer/aggbug/99653.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/baoyaer/" target="_blank">大田斗</a> 2007-02-13 11:28 <a href="http://www.blogjava.net/baoyaer/articles/99653.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>