`
dingjun1
  • 浏览: 213218 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

lucene应用入门1

阅读更多
简单的建立索引和索引查询
org.apache.lucene.index
                   ---IndexWriter

一个IndexWriter创建和维护一个index

参数create会建议构造方法,决定是一个新的index被创建,或打开一个已经存在的index。
甚至IndexReader正在使用这个Index,你也可以设置create=true打开该index,旧的IndexReader 对象会继续查询已经使用“时间点”快照的index,不会看到最新的创建的Index直到IndexReader对象被重新打开.
IndexWriter也可以不使用create参数构造对象,如果在提供给该对象路上Index不存在,IndexWriter对象会创建一个新的索引,否则会打开一个存在的Index。

在上述两种情况中,使用addDocument()增加documents,使用deleteDocuments(Term)或deleteDocuments(Query)移除documents,使用updateDocument()更新document(更新仅仅是删除后添加整个document),在完成文档增删改后,应该调用close()文法关闭IndexWriter.

这些变更会缓存在内存中,定期地flush到Directory,从最近一次flush后当删除的document被缓存到一定量时( setMaxBufferedDeleteTerms(int)),或者添加的document缓存到一定的量,flush会被触发调用。添加documents时,用于存放document内存容量(setRAMBufferSizeMB(double))或数目达到设定的量都会触发flush。默认当内存容量达到16MB会触发flush。你可以通过设定一个大的内存容量提高建立索引的速度。注意,刷新缓冲时,只移除在IndexWriter对象内的缓存状态,输出到INDEX。这些改变在执行commit或close前,对IndexReader是不可见的。一次缓存输出可能引发一次或多次segment合并,合并默认运行在后台的一个线程中,因此不会阻断addDocument的调用。

构造方法的可以选择的autoCommit方法控制IndexReader对象感知同一个index的更改,当为false,更改不会被感知,直到调用close()或commit(),更改会做为一个新的

文件被冲刷到directory,但是不会执行(不会有新的segments_N 文件引用新的文件进行写操作,也不会同步进行持久存储),直到close()被调用。在调用close()前,某个原因导致了一个严重的错误,index不会更改(它会保持它开

始时的状态),你也可以调用rollback(),关闭写入流,不会提交任何的更改,同时删除所有flush而没有被使用的index文件。这是很有用的对实行简单的单一写事务性的semantics.你可以做两个阶段的提交,调用commit()前先调用prepareCommit()。当LUCENE与外部资源(比如:数据库)一起工作时,两个必须一起提交或者回退事务。

当autoCommit为true是,IndexWriter对象会周期性的自己提交(Deprecated:3.0,IndexWriter 将不会再接受autoCommit=true,这会引起hardwire失败)。你可以根据需要一直调用commit()。不能保证自动执行会被执行(这个被使用在每次完全合并后。Version2.4)如果强制提交可以调用commit()或者关闭writer。当运行在这种模式下,注意在优化或者进行segment合并时不要刷新reader,这会占用大量的磁盘空间。
无论是不是autoCommit,IndexReader或者IndexSearcher只会看到在Index打开时的那个时间点的内容。任何在reader打开后提交的内容,对其是不可见的,直到reader被重新打开。

如果Index不会添加大量的documents,同时需要最佳的查询性能,这时用于全部优化的optimize()方法或者用于部分优化的optimize(int)方法应该在Index关闭前调用。

IndexWriter对象在使用中,会生成一个对目录的锁文件,试着在同一个目录打开另一个IndexWriter对象将会导致LockObtainFailedException。如果一个IndexReader对象在同一个目录用于从索引中删除documents时,这个异常也会被抛出。


org.apache.lucene.document
----Document
Document 是建索引和查询的功能单位,一个Document是一组field,每一个field有一个名称和一个文本值,一个field可能存放在Document中,它是

在Document中被查询命中后做为返回值,因此每一个document应该代表性包含一个或多个存储型的field用来唯一标识它。
field没有被存储在document中,不允许从索引中取回(比如使用ScoreDoc.doc Searcher.doc(int) IndexReader.document(int))

Document doc = new Document();
doc.add(Fieldable field)添加一个field到document中
String doc.get(String name),返回指定名称field的字符值,如果不存在则返回NULL
Fieldable doc.getField(String name)返回给定名称的field,如果不存在则返回null
doc.removeField(String name)移除给定名称的field
List getFields()返回在Document中的所有field
doc.setBoost()//设置权重因子


java.lang.Object
  org.apache.lucene.document.AbstractField
      org.apache.lucene.document.Field
----Field
field是document中的一部分,每一个field有两个部分,名称和值,值可以是做为字符串或者Reader流提供,它们可能是一个原子性的关键字,

它不用进一步处理,这些关键字可能是日期,链接等,字段被选择性地存储在索引中,以使它们可能做为document中的命中点被返回。
Field.Index:详细指明这个field是否要建索引,或者以什么样的方式建索引
Field.Index.NO:不对这个字段建索引,因此这个字段是不会被查询到的,如文档的路径、属性可能我们不想让它被检索到
Field.Index.NO_NORMS:建立索引,但是不对它进行分词索引,存储的规范不起作用,索引时,将不考虑权重因子和Field长度标准,优点就

是它占较小的内存,所在的字段开始索引时都是这种状态。(Index the field's value without an Analyzer, and disable the storing of

norms. No norms means that index-time boosting and field length normalization will be disabled. The benefit is less memory usage as

norms take up one byte per indexed field for every document in the index. Note that once you index a given field <i>with</i> norms

enabled, disabling norms will have no effect. In other words, for NO_NORMS to have the above described effect on a field, all

instances of that field must be indexed with NO_NORMS from the beginning.)
Field.Index.TOKENIZED:分词建索引
Field.Index.UN_TOKENIZED:不使用分词器对其值建索引,如日期,作者等
Field.Store:详细指明这个field是否存储,或都以什么样的方式存储。
Field.TermVector:条件向量

Field(String name, Reader reader) :分词索引,但是不存储,相当于Field(String name,String

value,Field.Store.NO,Field.Index.TOKENIZED)
Field(String name, String value, Field.Store store, Field.Index index) :指定存储情况、索引情况。
Field(String name, String value, Field.Store store, Field.Index index, Field.TermVector termVector) :



org.apache.lucene.search.Searcher
      org.apache.lucene.search.IndexSearcher
应用常常只需要通过Searcher.search(Query) 或者Searcher.search(Query,Filter)的方法继承得到。由于执行效率的原因,推荐在使用所有的查询

时,只打开同一个IndexSearcher。
注意:你只能在IndexSearcher没有关闭的期间,可以访问命中点集合,或则会抛IOException


org.apache.lucene.queryParser.QueryParser
这个类是,由JAVACC产生,最重要的方法就是parse(String),查询语法如下:
加号(+)或是减号(-),分别标志一个必须的条件或者一个禁用的条件,
由一个冒号(:)开头的条件,表示查询的field,这能够构造一个查询多个field的查询。

查询的句子可能是其中一种:
一个条件,表示所有的document符合这个条件,或者是一个嵌套的查询,由括号包裹,用+\-做为前缀使用于一组条件
查询语法如下:
Query ::=(Clause)*
Clause ::= ["+","-"][<TERM>":"](<TREM>|"("QUERY")")

评分机制
如果你想对每一个查询都设置权重因子在(评分时加大权重)标题field,使用你的查询句子用Query.setBoost()设置权重因子在你的标题field是最容

易的。
Field.setBoost()应该只使用在不同的Document中给不同的field设置权重因子时才使用,所以在查询时给所有的标题加相同的数值的权重因子是比较

容易的。这种方式可以试验权重数值,而不用重建索引,Field.setBoost()设置的值被建立在索引中,因而很难被改变。因此我推荐使用

Query.setBoost()来代替,为每一个查询的field构造成一个Query(自己编码,或者使用QueryParser),单独为每一个查询的field设置权重因子,然

后在执行时,联合这些查询建立一个逻辑查询(BooleanQuery)。我想这是有意义的。
If you wish to boost the title field for every query then it would be
easiest to boost the title clause of your query, with Query.setBoost().
Field.setBoost() should only be used when you want to give a field
different boosts in different documents, but since you want to boost all
titles by the same amount, you'll find it easier to boost at query time.
That way you can experiment with the boost amount without re-building
the index.  The values of Field.setBoost() are built into the index and
are harder to change.  Thus I recommend using Query.setBoost() instead.
Construct a query for each field to be searched (by hand, or with the
QueryParser), boost each of these field queries separately, then build a
BooleanQuery that combines these into a single Query that you then
execute.  I hope that makes sense.

package learn;


/**
 * 建立索引
 * @author Administrator
 *
 */
import java.io.*;
import org.apache.lucene.index.*;
import org.apache.lucene.store.*;
import org.apache.lucene.analysis.standard.*;
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.cn.*;
import org.apache.lucene.document.*;

public class BuildIndex {
	private final static String INDEX_DIR_PATH="e:\\index";
	private final static String test_dir="e:\\txt";
	/**
	 * @param args
	 */
	/**
	 * 获得IndexWriter对象
	 */
	public IndexWriter getIndexWriter(Directory indexDir,Analyzer analyzer) throws IOException{
		return new IndexWriter(indexDir,false,analyzer,true);
	}
	
	/**
	 * 建立索引
	 * @throws IOException
	 */
	public void build() throws IOException {
		Directory indexDir = FSDirectory.getDirectory(INDEX_DIR_PATH);
		Analyzer analyzer = new ChineseAnalyzer();
		
		IndexWriter writer = getIndexWriter(indexDir,analyzer);
		indexFile(writer,new File(test_dir));
		writer.flush();
		writer.optimize();
		writer.close();
		
		
	}
	
	/**
	 * 索引所有文件
	 * @param writer
	 * @param f
	 * @throws IOException
	 */
	public void indexFile(IndexWriter writer,File f) throws IOException{
		
		if(!f.exists()){
			throw new IOException("文件不存在");
		}
		if(f.isDirectory()){
			File[] fArr = f.listFiles();
			for(int i=0;i<fArr.length;i++){
				indexFile(writer,fArr[i]);//递归
			}
		}else{
			FileReader fr = new FileReader(f);
			Document doc = new Document();
			doc.add(new Field("content",fr));//建立索引,不存储
			doc.add(new Field("path",f.getAbsolutePath(),Field.Store.YES,Field.Index.NO));//存储不建索引
			writer.addDocument(doc);//添加记录
		}
	}
	
	public static void main(String[] args) throws IOException{
		BuildIndex build = new BuildIndex();
		build.build();

	}

}



package learn;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cn.ChineseAnalyzer;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.queryParser.*;
import org.apache.lucene.document.*;
import java.io.*;

public class TestSearch {
	private static IndexSearcher searcher = null;
	private final static String INDEX_DIR_PATH="e:\\index";
	
	public IndexSearcher getInstance() throws IOException{
		if(searcher==null){
			Directory indexDir = FSDirectory.getDirectory(INDEX_DIR_PATH);
			
			searcher = new IndexSearcher(indexDir);
		}
		return searcher;
	}
	
	/**
	 * 查询
	 * @param searchStr
	 * @throws IOException
	 * @throws ParseException
	 */
	public void search(String searchStr) throws IOException,ParseException{
		Analyzer analyzer = new ChineseAnalyzer();
		Query q =new QueryParser("content",analyzer).parse(searchStr);
		Hits hits = getInstance().search(q);
		HitIterator it = (HitIterator)hits.iterator();
		while(it.hasNext()){
			Document doc = ((Hit)it.next()).getDocument();
			System.out.println("path:"+doc.getField("path")+"");
		}
	}
	
	
	public static void main(String[] args) throws IOException,ParseException{
		TestSearch test = new TestSearch();
		test.search("网页 OR 服务器");
	}
	
}

分享到:
评论

相关推荐

    lucene 入门

    **Lucene 入门** Lucene 是一个高性能、全文本搜索库,由Apache软件基金会开发。它是Java平台上的一个开源项目,广泛应用于各种搜索引擎的构建,包括网站内部搜索、数据库索引等。Lucene 提供了强大的文本分析、...

    Lucene-入门

    **标题:“Lucene-入门”** Lucene是一个高性能、全文本搜索库,由Apache软件基金会开发并维护。它是Java编写的一个开源项目,被广泛应用于构建搜索引擎或者在大型数据集上进行全文检索。Lucene提供了丰富的搜索...

    lucene3.6的入门案例

    **Lucene 3.6 入门案例** Lucene 是一个高性能、全文本搜索库,由 Apache 软件基金会开发。它提供了完整的搜索功能,包括索引、查询、评分等,广泛应用于各种项目和产品中。在这个入门案例中,我们将深入理解如何...

    Lucene2.4入门总结

    **Lucene 2.4 入门指南** Lucene 是一个高性能、全文本搜索库,由 Apache 软件基金会开发。它提供了高级文本检索功能,广泛用于构建搜索引擎和其他需要高效全文检索能力的应用。本文将重点介绍 Lucene 2.4 版本的...

    Lucene 的入门 实例 代码

    1. **平台独立性**:Lucene 的索引文件格式是基于8位字节的,这使得不同平台的应用程序可以共享同一份索引,增强了跨平台兼容性。 2. **分块索引**:Lucene 实现了分块索引技术,允许快速索引新数据并能通过合并...

    lucene3.0.0 入门DEMO

    在这个"lucene3.0.0 入门DEMO"中,我们将探讨如何使用 Lucene 3.0.0 版本进行基本操作。 首先,让我们了解Lucene的核心概念: 1. **索引**:在Lucene中,索引是文档内容的预处理结果,类似于数据库中的索引,用于...

    lucene3.6入门实例教程

    《Lucene 3.6 入门实例教程》是一份专为初学者设计的指南,旨在帮助用户快速掌握Apache Lucene 3.6版本的基本概念和应用。Lucene是一个高性能、全文检索库,广泛用于构建搜索功能强大的应用程序。这份教程通过完整的...

    lucene 3.0 入门实例

    **Lucene 3.0 入门实例** Lucene 是一个高性能、全文本搜索库,由 Apache 软件基金会开发。它提供了完整的搜索功能,包括索引、查询解析、排序以及高级的文本分析能力。在 Lucene 3.0 版本中,开发者可以利用其强大...

    lucene入门小例子

    在实际应用中,一个完整的Lucene流程大致如下: 1. 初始化:创建Analyzer,用于分词;创建Directory,作为索引的存储位置,如内存目录RAMDirectory或磁盘上的FSDirectory。 2. 创建索引:创建IndexWriter对象,...

    lucene.net+完全入门教程

    10. **应用实例**: Lucene.Net常用于网站的搜索功能、大数据分析、日志分析、电子邮件搜索以及任何需要快速全文检索的场合。 通过学习这个“lucene.net+完全入门教程”,开发者可以了解如何在.NET环境中设置Lucene...

    lucene学习入门程序

    1. **Lucene核心组件** - **Analyzer**: 分析器是Lucene处理文本的关键组件,它将输入的字符串分解为可搜索的术语。在本程序中,你可能会看到不同类型的Analyzer,如StandardAnalyzer,用于处理英文文本,它会进行...

    Lucene 2.4 入门例子

    **Lucene 2.4 入门例子** Lucene 是一个高性能、全文本搜索库,由Apache软件基金会开发。它提供了强大的搜索功能,被广泛应用于各种应用中的信息检索。在这个入门例子中,我们将探讨Lucene 2.4版本的一些关键特性和...

    Lucene3.0入门实例含jar包

    **Lucene 3.0 入门实例及关键知识点** ...总之,Lucene 3.0 入门实例提供了理解全文搜索引擎工作原理的基础,通过实践,开发者能够熟练掌握如何在自己的应用程序中集成和利用 Lucene 实现高效、精准的文本搜索功能。

    最新全文检索 lucene-5.2.1 入门经典实例

    1. **Lucene核心组件** - **Analyzer**:文本分析器是Lucene处理文本的第一步,它负责将输入的字符串分解为一系列的词项(tokens)。在5.2.1版本中,包括了`StandardAnalyzer`和`SimpleAnalyzer`等,适用于不同语言...

    Lucene 3.0完成入门

    1. **Lucene 3.0 的基础概念** - **索引**:Lucene 的核心是索引,它是一种预处理步骤,将文档内容转换为便于快速搜索的数据结构。 - **分词**:Lucene 使用分词器(Tokenizer)将文档拆分为单独的词汇项(Tokens...

    [Lucene] Lucene入门心得

    【Lucene】Lucene入门心得 Lucene是一个高性能、全文本搜索库,由Apache软件基金会开发,被广泛应用于各种搜索引擎的构建。它提供了一个简单的API,使得开发者可以方便地在自己的应用程序中集成全文检索功能。...

    Lucene入门demo

    **Lucene 入门教程** Lucene 是一个高性能、全文本搜索库,由 Apache 软件基金会开发。...通过实践“Lucene入门demo”,你可以亲手创建并测试一个简单的 Lucene 搜索应用,进一步加深对 Lucene 工作原理的理解。

Global site tag (gtag.js) - Google Analytics