Lucene的核心索引类:
1、IndexWriter:建立索引的核心组件。
2、Directory:代表一个lucene索引项的位置。
3、Analyzer:对文本内容进行分析的抽象类,具体实现中有停用词切除 、词干分析、大小写切换等功能。
4、Document:可以视作文本经过处理后所对应的对象,由多个字段组成 ,如路径、标题、摘要、修改日期等等。
5、Field:字段 ,对应于文本的某一部分数据,便于检索时根据结果提取。早期版本分为四个类型:Keyword、UnIndexed、UnStored和Text,其主要区别归结于三个方面:是否被分析,是否被索引,是否存储于索引中。但是在最新版本的Lucene中,使用了一种更为统一的形式,也即只有Field一个类,然后使用一些参数来描述这个字段的属性,通过参数组合,可以组合出各种类别,甚至那四种不存在的类别理论上也是可以组合出来。
public Field (String name, String value, Store store, Index index)
下面来看一个例子代码:
package com.qianyan.luceneIndex; import java.io.IOException; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; public class IndexTest { public static void main(String[] args) throws IOException{ String[] ids = {"1", "2", "3"}; String[] names = {"zhangsan", "lisi", "wangwu"}; String[] addresses = {"shanghai", "beijing", "guangzhou"}; Analyzer analyzer = new StandardAnalyzer(); String indexDir = "E:/luceneindex"; Directory dir = FSDirectory.getDirectory(indexDir); //true 表示创建或覆盖当前索引;false 表示对当前索引进行追加 //Default value is 128 IndexWriter writer = new IndexWriter(dir, analyzer, true, IndexWriter.MaxFieldLength.LIMITED); for(int i = 0; i < ids.length; i++){ Document document = new Document(); document.add(new Field("id", ids[i], Field.Store.YES, Field.Index.ANALYZED)); document.add(new Field("name", names[i], Field.Store.YES, Field.Index.NOT_ANALYZED)); document.add(new Field("address", addresses[i], Field.Store.YES, Field.Index.ANALYZED)); writer.addDocument(document); } writer.optimize(); writer.close(); } }运行后查看 E:/luceneindex 会看到生成的索引文件。
删除索引:
package com.qianyan.luceneIndex; import java.io.IOException; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; public class TestDelDocument { public static void main(String[] args) throws IOException{ String indexDir = "E:/luceneindex"; Directory dir = FSDirectory.getDirectory(indexDir); IndexReader reader = IndexReader.open(dir); System.out.println(reader.maxDoc()); //直接根据序号删除索引 注:从0开始 //reader.deleteDocument(0); //根据索引值名删除索引 //reader.deleteDocuments(new Term("id", "3")); System.out.println(reader.numDocs()); reader.close(); dir.close(); } }
取消删除标记索引:
package com.qianyan.luceneIndex; import java.io.IOException; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; public class UnDeleteDocument { public static void main(String[] args) throws IOException { String indexDir = "E:/luceneindex"; Directory dir = FSDirectory.getDirectory(indexDir); IndexReader reader = IndexReader.open(dir); System.out.println("before delete:" + reader.numDocs()); reader.deleteDocuments(new Term("id", "1")); System.out.println("after delete:" + reader.numDocs()); reader.undeleteAll(); System.out.println("after undelete:" + reader.numDocs()); reader.close(); dir.close(); } }
package com.qianyan.luceneIndex; import java.io.IOException; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; public class UpdateDocument { public static void main(String[] args) throws IOException{ Analyzer analyzer = new StandardAnalyzer(); String indexDir = "E:/luceneindex"; Directory dir = FSDirectory.getDirectory(indexDir); IndexReader reader = IndexReader.open(dir); System.out.println("before delete : " + reader.numDocs()); reader.deleteDocuments(new Term("id", "2")); System.out.println("after delete : " + reader.numDocs()); reader.close(); IndexWriter writer = new IndexWriter(dir, analyzer, false, IndexWriter.MaxFieldLength.LIMITED); Document document = new Document(); document.add(new Field("id", "2", Field.Store.YES, Field.Index.ANALYZED)); document.add(new Field("name", "Tom", Field.Store.YES, Field.Index.ANALYZED)); document.add(new Field("address", "tianjin", Field.Store.YES, Field.Index.ANALYZED)); writer.addDocument(document); writer.close(); reader = IndexReader.open(dir); System.out.println("after add : " + reader.numDocs()); dir.close(); reader.close(); } }
在lucene中搜索算法的score简单说是由 tf * idf * boost * lengthNorm计算得来的。
tf:是查询的词在文档中出现的次数的平方根
idf:表示反转文档频率。
boost:激励因子,可以通过setBoost方法设置,需要说明的通过field和doc都可以设置,所设置的值lengthNorm,是由搜索的field的长度决定了,越长文档的分值越低。
控制score的就是设置boost值。
lucene会把计算后,最大分值超过1.0的分值作为分母,其他的文档的分值都除以这个最大值,计算出最终的得分。
document.setBoost(0.5f); //不太重要
document.setBoost(1.5f); //比较重要
field.setBoost(0.5f); //不太重要
field.setBoost(1.5f); //比较重要
lucene索引效率设置:
setMaxBufferedDocs 16MB
setMergeFactor 10
setMaxMergeDocs Inter.Max_VALUE;
Directory dir = FSDirectory.getDirectory(indexDir); //文件系统读取,IO操作
Directory dir = RAMDirectory(); //内存读取,效率高,容量小