zoukankan      html  css  js  c++  java
  • 解决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,经测试 完美解决问题

        

  • 相关阅读:
    二叉树非递归先中后序遍历 及 非递归交换二叉树两个孩子的位置
    COM 学习小记录
    Linux 信号量 生产者消费者小例题
    打印数字 形状有点得味
    (链表)链表倒序
    C++ 数组名作为函数参数 都是我的错
    进程 线程
    《C++ Qt 设计模式》8|15拼图 小游戏的简单实现。拜托,别乱点!
    PMAC运动程序例程(一)
    中国获得2022年冬奥会举办权【经济学人】
  • 原文地址:https://www.cnblogs.com/fanwenhao/p/9689154.html
Copyright © 2011-2022 走看看