lucene中Field.Index,Field.Store详解

本文详细介绍了Lucene中不同字段的索引与存储策略,包括如何选择合适的配置以满足搜索需求,如分词、不分词、存储与否等,并通过实例解释了各种配置的应用场景。

lucene在doc.add(new Field("content",curArt.getContent(),Field.Store.NO,Field.Index.TOKENIZED));

Field有两个属性可选:存储和索引。

通过存储属性你可以控制是否对这个Field进行存储;

通过索引属性你可以控制是否对该Field进行索引。

事实上对这两个属性的正确组合很重要。

Field.IndexField.Store说明
TOKENIZED(分词)YES被分词索引且存储
TOKENIZEDNO被分词索引但不存储
NOYES这是不能被搜索的,它只是被搜索内容的附属物。如URL等
UN_TOKENIZEDYES/NO不被分词,它作为一个整体被搜索,搜一部分是搜不出来的
NONO没有这种用法


我们那文章表为例.articleinfo.有ID,title(标题),sumary(摘要),content(内容),userName(用户名)

其中title(标题),sumary(摘要)属于第一种情况,既要索引也要分词,也要存储.

content(内容)要分词,索引,但不存储.由于他太大了,而且界面也不用显示整个内容.

ID要存储,不用索引.因为没人用他来查询.但拼URL却很需要他.索引要存储.

userName(用户名)索引,但不分词.可用保存.为什么不分词?比如"成吉思汗",我不想被"成汉"搜索到.我希望要么"成吉思汗"或者"*吉思*"通配符搜到.

总结如下:

1.如果要对某Field进行查找,那么一定要把Field.Index设置为TOKENIZED或UN_TOKENIZED。TOKENIZED会对Field的内容进行分词;而UN_TOKENIZED不会,只有全词匹配,该Field才会被选中。
2.如果Field.Store是No,那么就无法在搜索结果中从索引数据直接提取该域的值,会使null。

补充:

Field.Store.YES:存储字段值(未分词前的字段值)
Field.Store.NO:不存储,存储与索引没有关系
Field.Store.COMPRESS:压缩存储,用于长文本或二进制,但性能受损

Field.Index.ANALYZED:分词建索引
Field.Index.ANALYZED_NO_NORMS:分词建索引,但是Field的值不像通常那样被保存,而是只取一个byte,这样节约存储空间
Field.Index.NOT_ANALYZED:不分词且索引
Field.Index.NOT_ANALYZED_NO_NORMS:不分词建索引,Field的值去一个byte保存

TermVector表示文档的条目(由一个Document和Field定位)和它们在当前文档中所出现的次数
Field.TermVector.YES:为每个文档(Document)存储该字段的TermVector
Field.TermVector.NO:不存储TermVector
Field.TermVector.WITH_POSITIONS:存储位置
Field.TermVector.WITH_OFFSETS:存储偏移量
Field.TermVector.WITH_POSITIONS_OFFSETS:存储位置和偏移量

package com.boe.cim.teacher.luence; import java.nio.file.Paths; import java.util.List; import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.IntField; import org.apache.lucene.document.StringField; import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import com.boe.cim.teacher.pojo.RequirementInfo; /** * @author hyh * @description 创建文档索引 */ public class LuceneIndexRequirement { private Directory dir; /** *实例化indexerWriter * @return * @throws Exception */ private IndexWriter getWriter()throws Exception{ //中文分词器 SmartChineseAnalyzer analyzer=new SmartChineseAnalyzer(); IndexWriterConfig iwc=new IndexWriterConfig(analyzer); IndexWriter writer=new IndexWriter(dir, iwc); return writer; } /** * 获取indexreDir * @param indexreDir * @throws Exception */ // public void index(String indexreDir, List<RequirementInfo> listRequirement) throws Exception { // dir = FSDirectory.open(Paths.get(indexreDir)); // IndexWriterConfig iwc = new IndexWriterConfig(new SmartChineseAnalyzer()); // iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND); // 明确指定打开模式 // try (IndexWriter writer = new IndexWriter(dir, iwc)) { // for (RequirementInfo requirement : listRequirement) { // Document doc = new Document(); // doc.add(new StringField("id", String.valueOf(requirement.getId()), Field.Store.YES)); // doc.add(new StringField("requirement", requirement.getRequirement(), Field.Store.YES)); // doc.add(new StringField("department", requirement.getDepartment(), Field.Store.YES)); // doc.add(new StringField("liaisonman", requirement.getLiaisonman(), Field.Store.YES)); // doc.add(new StringField("requirementtype", Integer.toString(requirement.getRequirementtype()), Field.Store.YES)); // doc.add(new TextField("requirementbackground", requirement.getRequirementbackground(), Field.Store.YES)); // doc.add(new TextField("requirementcontents", requirement.getRequirementcontents(), Field.Store.YES)); // writer.updateDocument(new Term("id", String.valueOf(requirement.getId())), doc); // } // } // } public void index(String indexreDir,List<RequirementInfo> listRequirement)throws Exception{ dir=FSDirectory.open(Paths.get(indexreDir)); IndexWriter writer=getWriter(); writer.commit(); for(int i=0;i<listRequirement.size();i++){ Document doc=new Document(); RequirementInfo requirement = listRequirement.get(i); //StringField 只索引不分词 doc.add(new StringField("id",String.valueOf(requirement.getId()), Field.Store.YES)); doc.add(new StringField("requirement", requirement.getRequirement(), Field.Store.YES)); doc.add(new StringField("department",requirement.getDepartment(),Field.Store.YES)); doc.add(new StringField("liaisonman", requirement.getLiaisonman(), Field.Store.YES)); doc.add(new StringField("requirementtype", Integer.toString(requirement.getRequirementtype()), Field.Store.YES)); doc.add(new StringField("technicalfield", requirement.getTechnicalfield(), Field.Store.YES)); doc.add(new TextField("requirementbackground", requirement.getRequirementbackground(), Field.Store.YES)); doc.add(new TextField("requirementcontents", requirement.getRequirementcontents(), Field.Store.YES)); // doc.add(new StringField("requirementtype", Integer.toString(requirement.getRequirementtype()), Field.Store.YES)); // doc.add(new TextField("requirementbackground", requirement.getRequirementbackground(), Field.Store.YES)); // doc.add(new TextField("requirementcontents", requirement.getRequirementcontents(), Field.Store.YES)); // writer.deleteDocuments(new Term("id",String.valueOf(teacher.getId()))); writer.updateDocument(new Term("id",String.valueOf(requirement.getId())), doc); } writer.close(); } // public void indexSingleRequirement(String indexreDir, RequirementInfo requirement) throws Exception { // dir = FSDirectory.open(Paths.get(indexreDir)); // try (IndexWriter writer = getWriter()) { // Document doc = new Document(); // doc.add(new StringField("id",String.valueOf(requirement.getId()), Field.Store.YES)); // doc.add(new StringField("requirement", requirement.getRequirement(), Field.Store.YES)); // doc.add(new StringField("department",requirement.getDepartment(),Field.Store.YES)); // doc.add(new StringField("liaisonman", requirement.getLiaisonman(), Field.Store.YES)); // doc.add(new StringField("requirementtype", Integer.toString(requirement.getRequirementtype()), Field.Store.YES)); // doc.add(new StringField("technicalfield", requirement.getTechnicalfield(), Field.Store.YES)); // doc.add(new TextField("requirementbackground", requirement.getRequirementbackground(), Field.Store.YES)); // doc.add(new TextField("requirementcontents", requirement.getRequirementcontents(), Field.Store.YES)); // // 添加其他字段... // writer.updateDocument(new Term("id", String.valueOf(requirement.getId())), doc); // } // try-with-resources 自动关闭writer // } } package com.boe.cim.teacher.luence; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.core.annotation.Order; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Recover; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Component; import com.boe.cim.teacher.dao.TeacherInfoMapper; import com.boe.cim.teacher.pojo.TeacherInfo; import com.boe.cim.teacher.dao.RequirementInfoMapper; import com.boe.cim.teacher.pojo.RequirementInfo; import com.boe.cim.teacher.utils.FileOperationFunction; import lombok.extern.slf4j.Slf4j; @Slf4j @Component @Order(value=5) public class StartApplicationWithLuceneIndex implements ApplicationRunner{ @Value("${lucene.index.dir}") private String IndexDir; @Autowired private TeacherInfoMapper teacherInfoMapper; @Value("${lucenere.indexre.dir}") private String IndexreDir; @Autowired private RequirementInfoMapper requirementInfoMapper; @Override @Retryable(value= Exception.class,backoff=@Backoff(delay=2000)) //重试机制,默认重试三次,失败程序启动失败,Main函数run,异常直接捕获不了,因为被aop捕获了 public void run(ApplicationArguments args) { // TODO Auto-generated method stub FileOperationFunction.deleteFileFromPath(IndexDir); //有个文件权限太高,删不掉 log.info("生成教师索引文件ing..."); List<TeacherInfo> listTeacher = teacherInfoMapper.userTeacherInfoCreateLuceneIndex(); try { new LuceneIndex().index(IndexDir,listTeacher); } catch (Exception e) { // TODO Auto-generated catch block } log.info("生成教师索引文件成功,End"); // TODO Auto-generated method stub FileOperationFunction.deleteFileFromPath(IndexreDir); //有个文件权限太高,删不掉 log.info("生成需求索引文件ing..."); List<RequirementInfo> listRequirement = requirementInfoMapper.RequirementInfoCreateLuceneIndex(); try { new LuceneIndexRequirement().index(IndexreDir,listRequirement); } catch (Exception e) { // TODO Auto-generated catch block } log.info("生成需求索引文件成功,End"); } @Recover//重试多次皆失败回调方法 public void retryRecover(Exception e) { log.error("重试三次生成信息索引文件失败..."); log.error(e.getMessage()); } } 生成的是_0.fdt、_0.fdx
最新发布
09-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值