今天用了下Lucene,发现网上虽然也有不少介绍它的文档,不过很多都偏向介绍概念呀、设计或者是一些更为深入的东西,对于其入门使用的介绍性的文档并不多,就写了这么一篇。
				
						
								Lucene
						
						
								基本使用介绍
						
						
								
										
										
										
								
						
				
				
						
								
										 
								
						
				
				
						
								本文的目的不在于对
						
						
								Lucene
						
						
								的概念和设计这些进行介绍,仅在于介绍怎么样去使用
						
						
								Lucene
						
						
								来达到自己想要的几种常见的全文检索的需求,如果想深入了解
						
						
								Lucene
						
						
								的话本文不会带给你什么收获的。看完本文后想更深入的了解
						
						
								Lucene
						
						
								请访问:http://
						
						
								lucene.apache.org
						
				
				
						
								
										 
								
						
				
				
						
								
										一.  
								
						
						
								概述
						
						
								
										
										
								
						
				
				
						随着系统信息的越来越多,怎么样从这些信息海洋中捞起自己想要的那一根针就变得非常重要了,全文检索是通常用于解决此类问题的方案,而
						Lucene
						则为实现全文检索的工具,任何应用都可通过嵌入它来实现全文检索。
						
								
								
						
				
				
						
								
										二.  
								
						
						
								环境搭建
						
						
								
										
										
								
						
				
				
						从
						lucene.apache.org
						上下载最新版本的
						lucene.jar
						,将此
						jar
						作为项目的
						build path
						,那么在项目中就可以直接使用
						lucene
						了。
						
								
								
						
				
				
						
								
										三.  
								
						
						
								使用说明
						
						
								
										
										
								
						
				
				
						
								
										3.1.       
								
						
						
								基本概念
						
						
								
										
										
								
						
				
				
						这里介绍的主要为在使用中经常碰到一些概念,以大家都比较熟悉的数据库来进行类比的讲解,使用
						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
						中的相关信息了。
						
								
								
						
				
				
						通过对于上面在建立索引和全文检索的基本概念的介绍希望能让你对
						Lucene
						建立一定的了解。
						
								
								
						
				
				
						
								
										3.2.       
								
						
						
								全文检索需求的实现
						
						
								
										
										
								
						
				
				
						索引建立部分的代码:
						
								
								
						
				
				
						
								
										
										
								
						
				
				
						
								
								
								private
								 
								void
								 createIndex(String indexFilePath) throws Exception
								
										
								
								
										{

        IndexWriter iwriter
										=
										getWriter(indexFilePath);

        Document doc
										=
										new
										 Document();

        doc.add(Field.Keyword(
										"
										name
										"
										,
										"
										jerry
										"
										));

        doc.add(Field.Text(
										"
										sender
										"
										,
										"
										bluedavy@gmail.com
										"
										));

        doc.add(Field.Text(
										"
										receiver
										"
										,
										"
										google@gmail.com
										"
										));

        doc.add(Field.Text(
										"
										title
										"
										,
										"
										用于索引的标题
										"
										));

        doc.add(Field.UnIndexed(
										"
										content
										"
										,
										"
										不建立索引的内容
										"
										));

        Document doc2
										=
										new
										 Document();

        doc2.add(Field.Keyword(
										"
										name
										"
										,
										"
										jerry.lin
										"
										));

        doc2.add(Field.Text(
										"
										sender
										"
										,
										"
										bluedavy@hotmail.com
										"
										));

        doc2.add(Field.Text(
										"
										receiver
										"
										,
										"
										msn@hotmail.com
										"
										));

        doc2.add(Field.Text(
										"
										title
										"
										,
										"
										用于索引的第二个标题
										"
										));

        doc2.add(Field.Text(
										"
										content
										"
										,
										"
										建立索引的内容
										"
										));

        iwriter.addDocument(doc);

        iwriter.addDocument(doc2);

        iwriter.optimize();

        iwriter.close();

    }
								
								
										
										
										
										
    


    
								private
								 IndexWriter getWriter(String indexFilePath) throws Exception
								
										
								
								
										{

        boolean append
										=
										true
										;

        File file
										=
										new
										 File(indexFilePath
										+
										File.separator
										+
										"
										segments
										"
										);

        
										if
										(file.exists())

            append
										=
										false
										; 

        
										return
										 
										new
										 IndexWriter(indexFilePath,analyzer,append);

    }
								
								
										
										
										
										
								
						 
				 
				3.2.1.       对于某字段的关键字的模糊查询
				
						
								
										
										
								
						
				
				
						
								
								Query query
								=
								new
								 WildcardQuery(
								new
								 Term(
								"
								sender
								"
								,
								"
								*davy*
								"
								));

        

        Searcher searcher
								=
								new
								 IndexSearcher(indexFilePath);

        Hits hits
								=
								searcher.search(query);


        
								for
								 (
								int
								 i 
								=
								 
								0
								; i 
								<
								 hits.length(); i
								++
								) 
								
										
								
								
										{

            System.
										out
										.println(hits.doc(i).
										get
										(
										"
										name
										"
										));

        }
								
								
										
										
										
										
								
						 
				 
				3.2.2.       对于某字段的关键字的语义查询
				
						
								
										
										
								
						
				
				
						
								
								Query query
								=
								QueryParser.parse(
								"
								索引
								"
								,
								"
								title
								"
								,analyzer);

        

        Searcher searcher
								=
								new
								 IndexSearcher(indexFilePath);

        Hits hits
								=
								searcher.search(query);


        
								for
								 (
								int
								 i 
								=
								 
								0
								; i 
								<
								 hits.length(); i
								++
								) 
								
										
								
								
										{

            System.
										out
										.println(hits.doc(i).
										get
										(
										"
										name
										"
										));

        }
								
								
										
										
										
										
								
						 
				 
				3.2.3.       对于多字段的关键字的查询
				
						
								
										
										
								
						
				
				
						
								
								
								Query query
								=
								MultiFieldQueryParser.parse(
								"
								索引
								"
								,
								new
								 String[]
								
										
								
								
										{
										"
										title
										"
										,
										"
										content
										"
										}
								
								,analyzer);

        

        Searcher searcher
								=
								new
								 IndexSearcher(indexFilePath);

        Hits hits
								=
								searcher.search(query);


        
								for
								 (
								int
								 i 
								=
								 
								0
								; i 
								<
								 hits.length(); i
								++
								) 
								
										
								
								
										{

            System.
										out
										.println(hits.doc(i).
										get
										(
										"
										name
										"
										));

        }
								
								
										
										
										
										
								
						 
				 
				3.2.4.       复合查询(多种查询条件的综合查询)
				
						
								
										
										
								
						
				
				
						
								
								
								Query query
								=
								MultiFieldQueryParser.parse(
								"
								索引
								"
								,
								new
								 String[]
								
										
								
								
										{
										"
										title
										"
										,
										"
										content
										"
										}
								
								,analyzer);

        Query mquery
								=
								new
								 WildcardQuery(
								new
								 Term(
								"
								sender
								"
								,
								"
								bluedavy*
								"
								));

        TermQuery tquery
								=
								new
								 TermQuery(
								new
								 Term(
								"
								name
								"
								,
								"
								jerry
								"
								));

        

        BooleanQuery bquery
								=
								new
								 BooleanQuery();

        bquery.add(query,
								true
								,
								false
								);

        bquery.add(mquery,
								true
								,
								false
								);

        bquery.add(tquery,
								true
								,
								false
								);

        

        Searcher searcher
								=
								new
								 IndexSearcher(indexFilePath);

        Hits hits
								=
								searcher.search(bquery);


        
								for
								 (
								int
								 i 
								=
								 
								0
								; i 
								<
								 hits.length(); i
								++
								) 
								
										
								
								
										{

            System.
										out
										.println(hits.doc(i).
										get
										(
										"
										name
										"
										));

        }
								
								
										
										
										
										
								
						 
				 
				四.  总结
				
						相信大家通过上面的说明能知道
						Lucene
						的一个基本的使用方法,在全文检索时建议大家先采用语义时的搜索,先搜索出有意义的内容,之后再进行模糊之类的搜索,
						^_^
						,这个还是需要根据搜索的需求才能定了,
						Lucene
						还提供了很多其他更好用的方法,这个就等待大家在使用的过程中自己去进一步的摸索了,比如对于
						Lucene
						本身提供的
						Query
						的更熟练的掌握,对于
						Filter
						、
						Sorter
						的使用,自己扩展实现
						Analyzer
						,自己实现
						Query
						等等,甚至可以去了解一些关于搜索引擎的技术
						(
						切词、索引排序
						 etc)
						等等。
				
		 
	posted on 2006-05-06 01:52 
船长 阅读(206) 
评论(0)  编辑  收藏