在文章文档的增删改(上)中我们介绍了Lucene中提供的几个接口用来实现文档的更新:
- updateDocument(Term term, Iterable<? extends IndexableField> doc)
- updateDocuments(Term delTerm, Iterable<? extends Iterable<? extends IndexableField>> docs)
对于上述的两个更新操作,实际的处理过程为:先删除、后添加
,其中删除
在源码中用hardDelete描述,即硬删除(或者可以翻译为实删除),该过程为先删除包含term的文档,然后添加新的文档doc或批量添加新的文档集合docs。
- softUpdateDocument(Term term, Iterable<? extends IndexableField> doc, Field... softDeletes)
- softUpdateDocuments(Term term, Iterable<? extends Iterable<? extends IndexableField>> docs, Field... softDeletes)
对于上述的两个更新操作,实际的逻辑过程为:先标记、后添加
,其中标记
在源码中用softDeletes描述,即软删除,该过程为先标记包含term的文档,这些文档使用域名为softDeletes的DocValues域(为什么softDeletes参数允许多个,下文中会介绍)来描述该文档被软删除了,然后添加新的文档doc或批量添加新的文档集合docs。
软删除跟硬删除的差异
我们接着从使用方式、被删除的文档的描述方式、被删除的的文档的生命周期这几个方面来描述两者的差异。
使用方式
- 硬删除:不使用任何使用方式
- 软删除:需要在构造IndexWriter对象时指定一个软删除的域名softDeletesField,即在设置IndexWriter的配置信息IndexWriterConfig时通过调用IndexWriterConfig类提供的setSoftDeletesField方法来指定一个软删除的域名softDeletesField,如下所示,另外设置IndexWriter的配置信息IndexWriterConfig的内容可以查看文章构造IndexWriter对象(一):
图1:
被删除的文档的描述方式
- 硬删除:被删除的文档对应的文档号用索引文件.liv来描述。
- 软删除:被标记为删除的文档不使用索引文件.liv来描述,而是通过索引文件.dvd、dvm来描述,其具体介绍将在后面的内容中展开
被删除的文档的生命周期
- 硬删除:在执行段的合并之前,被删除的文档信息仍然在索引文件中,此时执行查询操作,如果被删除的文档满足查询条件,在查询的过程中仍然能获取这个文档号,只是在随后的逻辑中,通过索引文件.liv来实现过滤,使得不让这个文档号传递给Collector,并且最终根据段的合并策略,被删除的文档才会在合并的过程中实现物理删除,即索引文件中不存在该文档的信息。
- 软删除:在执行段的合并之前,被标记为删除的文档信息仍然在索引文件中,此时执行查询操作,如果被软删除的文档满足查询条件,在查询的过程中仍然能获取到这个文档,只是在随后的逻辑中,通过索引文件.dvm&&.dvd来实现过滤,使得不让这个文档号传递给Collector,与硬删除不同的是,软删除可以通过使用合并策略SoftDeletesRetentionMergePolicy使得在执行段的合并之后,这些被删除的文档仍然被保留在索引文件中,并且可以被搜索到;同样的还是通过配置合并策略SoftDeletesRetentionMergePolicy使得这些被删除的文档无法被搜索到,或者使这些被删除的文档在下一次合并中同硬删除一样,实现物理删除,合并策略SoftDeletesRetentionMergePolicy的介绍将在后面的内容中展开
看这里:https://www.amazingkoala.com.cn/Lucene/Index/2020/0616/148.html