lucene学习笔记3-索引-创建域选项

时间:2022-02-08 03:08:45

分词存储设置范围最佳实践:

分词索引:Field.Index.*

存储:Field.Store.YES/NO

适用范围

NOT_ANALYZED_NOT_NORMS

YES

标识符(主键、文件名),电话号码,身份证号,姓名,日期

ANALYZED

YES

文档标题和摘要

ANALYZED

NO

文档正文

NO

YES

文档类型,数据库主键(不进行索引)

NOT_ANALYZED

NO

隐藏关键字

 

import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class IndexUtil
{

private String[] ids = { "1", "2", "3", "4", "5", "6" };

private String[] emails = { "b1", "b2", "b3", "b4", "b5", "b6" };

private String[] content = { "b1 aaaa this is hello ",
"b2 i kill to you ma", "b3 cc wo are you from hold",
"b4 Index Reader", "b5 r RUNTIME DATA AREA",
"b6 java lang ClassLoader" };

private int[] attachs = { 2, 3, 1, 4, 5, 5 };

private String[] names = { "wc1", "wc2", "wc3", "wc4", "wc5", "wc6" };

private Directory directory = null;

public IndexUtil()
{

try
{
// 设置索引目录
directory = FSDirectory.open(new File("D:\\workspace\\helloLucene\\IndexUtil\\"));
}
catch (IOException e)
{
// TODO Auto-generated catch
// block
e.printStackTrace();
}
}

public void index()
{

IndexWriter writer = null;
try
{
writer = new IndexWriter(directory,
new IndexWriterConfig(Version.LUCENE_35,
new StandardAnalyzer(Version.LUCENE_35)));
Document doc = null;
for (int i = 0; i < ids.length; i++)
{
doc = new Document();
// id需要存储不分词不加权
doc.add(new Field("id",
ids[i],
Field.Store.YES,
Field.Index.NOT_ANALYZED_NO_NORMS));
// email需要存储不分词,希望区分公司邮件为重点-加权重
doc.add(new Field("email",
emails[i],
Field.Store.YES,
Field.Index.NOT_ANALYZED));
// content不存储分词
doc.add(new Field("content",
content[i],
Field.Store.NO,
Field.Index.ANALYZED));
// name需要存储不分词不加权
doc.add(new Field("name",
names[i],
Field.Store.YES,
Field.Index.NOT_ANALYZED_NO_NORMS));

writer.addDocument(doc);
}
}
catch (Exception e)
{
// TODO Auto-generated catch
// block
e.printStackTrace();
}
finally
{
try
{
if (writer != null)
{
writer.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

public void query() {
try {
IndexReader reader = IndexReader.open(directory);
//通过reader可以有效的获取到文档的数量
System.out.println("返回索引中的Document的数 numDocs:"+reader.numDocs());
System.out.println("下一个Document对象的编号 maxDocs:"+reader.maxDoc());
System.out.println("deleteDocs:"+reader.numDeletedDocs());
reader.close();
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

public static void main(String[] args)
{

IndexUtil iu = new IndexUtil();
iu.index();
iu.query();
System.out.println("end...");

}

}


 


Lucene使用文件扩展名标识不同的索引文件。如.fnm文件存储域Fields名称及其属性,.fdt存储文档各项域数据,.fdx存储文档在fdt中的偏移位置即其索引文件,.frq存储文档中term位置数 据,.tii文件存储term字典,.tis文件存储term频率数据,.prx存储term接近度数据,.nrm存储调节因子数据,另外 segments_X文件存储当前最新索引片段的信息,其中X为其最新修改版本,segments.gen存储当前版本即X值。 

 

它们的关系图则如下所示:

lucene学习笔记3-索引-创建域选项

FNM 保存Field域信息,代码中定义一致。

lucene学习笔记3-索引-创建域选项

第0x05字节表示存储了4个域

lucene学习笔记3-索引-创建域选项
FDX 保存Field域索引,保存了每个document的词域数据在.fdt的起始位置(每个位置数据用Uint64,8个字节)

如图:第0x03字节表示??,第0个document的词域数据信息起始于.fdt的第0x04字节,第1个document的词域数据信息起始于.fdt的第0x14字节。

lucene学习笔记3-索引-创建域选项


FDT 保存Field域数据,按document依次存储词域数据。每个词域数据信息包括该词域序号(FieldNum)、词域位信息(Bits)和词域数据。词域数据又分字符串和二进制2种类型。字符串数据包含字符个数(非字节数)和字符串内容,字符串内容是经过utf-8编码的。

如图:0x04字节表示该document有3个词域,第0x05-0x09字节表示第0个词域数据信息,其中第0x05、0x09字节表示词域序号,即FieldNum;第0x05字节表示词域位信息,即Bits;第0x07、0x0b表示词域数据字符长度,即1、2个;第0x08字节就是词域数据,即“1”,第0x0C、0x0D字节就是词域数据,即“b1”。。

lucene学习笔记3-索引-创建域选项

 

 FRQ 评分和排序,词语所在文档的文档列表(docID)和该词语出现在文档中的频率信息。
 TII 词典,索引文件。保存了tis中每隔IndexInterval个词的位置信息,这是为了加快对词典文件tii中词的查找速度
 TIS 词典数据文件。存放索引表中Dictionary的所有Term的信息