本篇文章主要介绍IndexReader,Directory,Analyzer的常见使用方法
IndexReader
IndexReader对象可以用于读取索引目录和按编号删除文档对象。这个类并不立即从索引中删除Document。它只做个删除的标志,等待IndexReader的close()方法调用时真正的Document删除。
dir = FSDirectory.open(indexFile); 打开IndexFile路径下的目录
IndexReader reader= IndexReader.open(dir); 读取目录下的索引文件
假设有两篇文档:
reader.delete(1); 删除号码为1的Document
assertTrue(reader.isDeleted(1)); 判断删除Document的结果
assertTrue(reader.hasDeletions()); 包含删除的索引
assertEquals(2,reader.maxDoc()); 这时候文档并没有真正的删除,文档数量还是2
reader.close();
reader= IndexReader.open(dir);
assertEquals(2,reader.maxDoc()); 在IndexReader重新打开后,
assertEquals(1,reader.numDocs()); 这时候文档就被删除了
reader.close();
这儿展示了IndexReader经常混淆的两个方法的不同:
maxDoc()和numDocs()。前者返回下一个可用的内部Document号,后者返回索引中的Document的数目。因为我们的索引只含有两个Document,numDocs()返回2;又因为Document号从0开始,maxDoc()也返回2。
注意:每个Lucene的Document有个唯一的内部编号。这些编码不是永久分配的,因为Lucene索引分配时在内部重新分配Document的编号。因此,你不能假定一个给定的Document总是拥有同一个Document编号。(所才有上文中利用组合域确定唯一文档的需要)
Directory
Directory类代表一个Lucene索引的位置。它是一个抽象类,允许它的子类(其中的两个包含在Lucene中)在合适时存储索引。在我们的Indexer示例中,我们使用一个实际文件系统目录的路径传递给IndexWriter的构造函数来获得Directory的一个实例。IndexWriter然后使用Directory的一个具体实现FSDirectory,并在文件系统的一个目录中创建索引。
在你的应用程序中,你可能较喜欢将Lucene索引存储在磁盘上。这时可以使用FSDirectory,一个包含文件系统真实文件列表的Driectory子类,如同我们在Indexer中一样。
另一个Directory的具体子类是RAMDirectory。尽管它提供了与
FSDirectory相同的接口,RAMDirectory将它的所有数据加载到内存中。所以这个实现对较小索引很有用处,可以全部加载到内存中并在程序关闭时销毁。因为所有数据加载到快速存取的内存中而不是在慢速的硬盘上,RAMDirectory适合于你需要快速访问索引的情况,不管是索引或搜索。
做为实例,Lucene的开发者在所有他们的单元测试中做了扩展使用:当测试运行时,快速的内存驻留索引被创建搜索,当测试结束时,索引自动销毁,不会在磁盘上留下任何残余。当然,在将文件缓存到内存的操作系统中使用时RAMDirectory和FSDirectory之间的性能差别较小。
Analyzer
在文本索前之前,它先通过Analyzer。Analyzer在IndexWriter的构造函数中指定,司职对文本内容提取关键词并除去其它的。如果要索引的内容不是普通的文本,首先要转化成文本。
Analyzer是个抽象类,但是Lucene中有几个它的实现。有的处理的时候跳过终止词(不能用来把某个文件与其它文件区分开的常用的词);有的处理时把关键字转化为小写字母,所以这个搜索不是大小写敏感等等。Analyzer是Lucene的一个重要的部分并且不只是在输入过滤中使用。对一个将Lucene集成到应用程序中的开发者来说,对Analyzer的选择在程序设计中是重要元素。
Document
一个Document代表字段的集合。你可以把它想象为以后可获取的虚拟文档—一块数据,如一个网页、一个邮件消息或一个文本文件。一个文档的字段代表这个文档或与这个文档相关的元数据。文档数据的最初来源(如一条数据库记录、一个Word文档、一本书的某一章等等)与Lucene无关。元数据如作者、标题、主题、修改日期等等,分别做为文档的字段索引和存储。
注意:当我们在本书中提到一个文档,我们指一个Microsoft Word、RTF、PDF或其它文档类型;我们不是谈论Lucene的Document类。注意大小写和字体的区别。
Lucene只用来处理文本。Lucene的核心只能用来处理java.lang.String和
java.io.Reader。尽管很多文档类型都能被索引并使之可搜索,处理它们并不像处理可以简单地转化为java的String或Reader类型的纯文本内容那样直接。
在我们的IndexWriter中,我们处理文本文件,所以对我们找出的每个文本文件,创建一个Document类的实例,用Field(字段)组装它,并把这个Document添加到索引中,完成对这个文件的索引。
Field
在索引中的每个Document含有一个或多个字段,具体化为Field类。每个字段相应于数据的一个片段,将在搜索时查询或从索引中重新获取。
Lucene提供四个不同的字段类型,你可以从中做出选择:
1、Keyword—不被分析,但是被索引并逐字存储到索引中。这个类型适合于原始值需要保持原样的字段,如URL、文件系统路径、日期、个人名称、社会安全号码、电话号码等等。例如,我们在IndexerWriter中把文件系统路径作为Keyword字段。
2、UnIndexed—不被分析也不被索引,但是它的值存储到索引中。这个类型适合于你需要和搜索结果一起显示的字段(如URL或数据库主键),但是你从不直接搜索它的值。因为这种类型字段的原始值存储在索引中,这种类型不适合于存放比较巨大的值,如果索引大小是个问题的话。
3、UnStored—和UnIndexed相反。这个字段类型被分析并索引但是不存储在索引中。它适合于索引大量的文本而不需要以原始形式重新获得它。例如网页的主体或任休其它类型的文本文档。
4、Text—被分析并索引。这就意味着这种类型的字段可以被搜索,但是要小心字段大小。如果要索引的数据是一个String,它也被存储;但如果数据(如我们的Indexer例子)是来自一个Reader,它就不会被存储。这通常是混乱的来源,所以在使用Field.Text时要注意这个区别。
所有字段由名称和值组成。你要使用哪种字段类型取决于你要如何使用这个字段和它的值。严格来说,Lucene只有一个字段类型:以各自特征来区分的字段。有些是被分析的,有些不是;有些是被索引,然面有些被逐字地存储等等。
不同字段类型的特征和使用方法
Fiedmethod/type
Analyzed
Indexed
Stored
Exampleusage
Field.Keyword(String,String)
Field.Keyword(String,Date)
Telephoneand Social Security numbers, URLs, personal names, Dates
Field.UnIndexed(String,
String)
Documenttype (PDF, HTML, and so on), if not used as search criteria
Field.UnStored(String,String)
Documenttitles and content
Field.Text(String,String)
Documenttitles and content
Field.Text(String,Reader)
注意:所有字段类型都能用代表字段名称和它的值的两个String来构建。另外,一个Keyword字段可以接受一个String和一个Date对象,Text字段接受一个String和一个Reader对象。在所有情况下,这些值在被索引之前都先被转化成Reader,这些附加方法的存在可以提供比较友好的API。
Field.Text(String,String)和Field.Text(String,Reader)之间的区别。String变量存储字段数据,而Reader变量不存储。为索引一个String而又不想存储它,可以用
Field.UnStored(String,String)。
最后,UnStored和Text字段能够用来创建词向量。为了让Lucene针对指定的UnStored或Text字段创建词向量,你可以使用Field.UnStored(String, String,
true),Field.Text(String, String, true)或Field.Text(String,Reader, true)。
Term
Term是搜索的基本单元。与Field对象类似,它由一对字符串元素组成:字段的名称和字段的值。注意Term对象也和索引过程有关。但是它们是由Lucene内部生成,所以在索引时你一般不必考虑它们。在搜索时,你可能创建Term对象并TermQuery同时使用。
Queryq = new TermQuery(new Term(“contents”, “lucene”));
Hitshits = is.search(q);
这段代码使Lucene找出在contents字段中含有单词lucene的所有文档。因为TermQuery对象继承自它的抽象父类Query,你可以在等式的左边用Query类型。
Query
Lucene中包含一些Query的具体子类。到目前为止,在本章中我们仅提到过最基本的Lucene Query:TermQuery。其它Query类型有BooleanQuery,PhraseQuery, PrefixQuery,PhrasePrefixQuery, RangeQuery,FilteredQuery和SpanQuery。Query是最基本的抽象父类。它包含一些通用方法,其中最有趣的是setBoost(float)-设置文档的权重值。
分享到:
相关推荐
以下是对Lucene常用功能的详细介绍: 1. **创建索引** 创建索引是Lucene工作的第一步。通过`Directory`接口,如`FSDirectory`,Lucene可以读写文件系统中的索引。`IndexWriter`类负责实际的索引构建过程,它允许...
`QueryParser`类是主要的入口点,它可以将简单的自然语言查询(如"北京天气")转化为Lucene可以理解的`Query`对象。同时,这个包还包含了一些查询构造函数,如`BooleanQuery`、`TermQuery`等,使得开发者能够构建...
然后,你可以使用`IndexReader.document(docNum)`获取实际的`Document`对象。 9. **Term** 和 **TermQuery**: `Term` 代表索引中的一个唯一的词项(term),`TermQuery` 是基于单一词项的查询,匹配包含该词项的...
工具类对IndexWriter,IndexReader,IndexSearcher,Analyzer,QueryParser等Lucene这些常用操作对象的获取进行了封装,其中IndexWriter采用了单例模式,确保始终只有一个对象实例,因为Lucene限制了索引写操作是阻塞的...
- `lucene-3.5.0.tgz`: 这是一个归档文件,使用tgz格式,解压后会得到Lucene 3.5.0版本的源代码。源代码包含了所有类、接口、方法和注释,是学习Lucene内部机制的关键。 4. **关键类和接口**: - `IndexWriter`: ...
- **作用**:提供了一些常用的工具类和常量类的支持。 #### 三、索引文件格式 Lucene使用多种文件格式来存储索引信息: - **fnm**:包含Document中所有Field的名称。 - **fdt** 和 **fdx**:.fdt文件用于存储具有...
- **StandardAnalyzer**:提供了较为复杂的分词机制,是最常用的分析器之一。 ##### 2. `document` 此模块定义了文档的数据结构,主要包括: - **Document**:表示一个文档,由多个Field组成。 - **Field**:表示...
`IndexWriter` 是 Lucene 中的核心类之一,用于创建或更新索引。它提供了添加文档、删除文档、优化索引等操作的功能。 **1.1.2 Directory** `Directory` 在 Lucene 中代表了存储索引的地方,可以是硬盘上的文件...
5. **近似搜索**: 使用模糊匹配或n-gram技术,允许一定程度的拼写错误,增加召回率。 6. **分布式搜索**: 在大型系统中,通过分布式搜索引擎如Solr或Elasticsearch,利用多台服务器并行处理,提高处理能力和响应...
2. **查询解析**:`QueryParser` 类用于将用户输入的查询字符串转化为 Lucene 可识别的查询对象。源码展示了如何处理布尔操作符、短语查询、字段限制等复杂查询结构。 3. **搜索执行**:`IndexSearcher` 类负责执行...
5. **处理结果**: 最后,遍历`ScoreDoc`数组,使用`IndexReader`或`Document`类获取匹配文档的详细信息。 **总结** Lucene的布尔搜索提供了一种灵活的方式来进行精确的文本检索。通过理解如何构造和使用`...
在这个搜索实例中,我们将探讨 Lucene 的基本使用和核心概念。 **一、Lucene 的基本架构** Lucene 的核心组件包括索引(Index)、文档(Document)、字段(Field)和查询(Query)。首先,我们需要将数据转化为 ...
9. **获取文档内容**:使用`IndexReader.document()`方法,传入文档编号,得到Document对象。 10. **提取查询结果**:从Document中通过Field的名称获取查询结果,如`document.get("group_id")`。 以上就是使用...
2. **创建IndexSearcher**: 使用IndexReader获取IndexSearcher实例。 3. **执行查询**: 调用IndexSearcher的search方法,传入Query对象。 4. **获取结果**: 返回ScoreDoc数组,表示匹配的文档及其相关性分数。 5. **...
把用户输入的查询字符串封装成Lucene能够识别的Query对象。 3) Filter: 用来过虑搜索结果的对象。 4) TopDocs: 代表查询结果集信息对象。它有两个属性: a) totalHits: 查询命中数。 b) scoreDocs: 查询结果信息...
5. 使用IndexWriter的addDocument方法将Document写入索引。 6. 最后,关闭IndexWriter以保存索引并释放资源。 通过上述步骤,开发者可以创建一个完整的Lucene索引,从而为应用程序提供快速的全文搜索功能。Lucene的...
- **使用缓存**:对于常用的查询结果进行缓存,减少重复计算。 - **优化索引结构**:合理的索引设计可以提高搜索效率。 - **利用过滤器**:使用过滤器来缩小搜索范围,减少不必要的计算。 - **并发控制**:合理地...