解决lucene更新删除无效的问题


个人博客 地址:http://www.wenhaofan.com/article/20180921233809

问题描述

 在使用deleteDocuments,updateDocument方法根据id字段删除更新索引时不抛异常但是删除更新失败

    writer.deleteDocuments(new Term("id", "1"));

解决问题

   在创建索引时使用到了lucene提供的StoreField TextField,而id字段的属性的类型为StoreField,当出现该问题时首先切换思路尝试根据content删除索引。

writer.deleteDocuments(new Term("content", "html"));
   果不其然,使用类型为TextField时便能正确的执行删除修改操作,但是由于TextField属性有一个特性 ,使用该类型的字段会被分词,这样便会出现一个问题。

   假如我们使用TextFiled来存储了一个id为123的字段,一个id值为12的字段。

   由于TextField类型的值会被分词,所以id值为123的文档可能会创建两个索引:12和123 ,id值为12的文档可能会创建一个索引:12     (实际情况或许不会如此,此处仅作演示)。

   此时如果我们想要删除id值为12的文档,便很有可能同时删掉id值为123的文档,因为他们有一个共同的索引值12。

    所以使用TextField来存储id值不是一个理想的解决方法,继续寻找其他的解决 方法。

    现在问题的原因基本上能够锁定在StoreFiled和TextField的差异上,所以进一步分析问题原因,

    最后通过阅读源码发现TextField设置了FieldType中的IndexOptions属性值为IndexOptions.DOCS_AND_FREQS_AND_POSITIONS,而StoredField中的FieldType并没有设置该属性

    于是修改建立索引时id所使用的Filed,代码修改如下

Field idField=new Field("id", String.valueOf(article.getId()), type)
修改为
FieldType type = new FieldType();
type.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS);
type.setTokenized(false);
type.setStored(true);
Field idField=new Field("id", String.valueOf(article.getId()), type); 

 此处新建了一个不进行分词,IndexOptions属性值为IndexOptions.DOCS_AND_FREQS_AND_POSITIONS,且存储在查询结果中的FieldType,经测试 完美解决问题

    

原文地址:https://www.cnblogs.com/fanwenhao/p/9689154.html