【问题标题】:Lucene 4.0 IndexWriter updateDocument for Numeric TermLucene 4.0 IndexWriter updateDocument 用于数字项
【发布时间】:2012-12-19 18:07:47
【问题描述】:

我只是想知道如何根据数字字段更新(删除/插入)文档。 到目前为止,我这样做了:

LuceneManager.updateDocument(writer, new Term("id",  NumericUtils.intToPrefixCoded(sentenceId)), newDoc);

但现在在 Lucene 4.0 中,NumericUtils 类已更改为 this,我不太明白。 有什么帮助吗?

【问题讨论】:

  • 您是否有特殊原因使用 NumericUtils 手动转换数字,而不是使用 NumericField
  • 好吧,因为 IndexWriter 想要一个术语,而我不知道任何其他方法可以为数字字段创建一个术语

标签: java lucene indexing


【解决方案1】:

使用 Lucene 5.x,这可以通过以下代码解决:

    int id = 1;
    BytesRefBuilder brb = new BytesRefBuilder();
    NumericUtils.intToPrefixCodedBytes(id, 0, brb);
    Term term = new Term("id", brb.get());
    indexWriter.updateDocument(term, doc); // or indexWriter.deleteDocument(term);

【讨论】:

    【解决方案2】:

    使用 Lucene 4,您现在可以像这样创建 IntFieldLongFieldFloatFieldDoubleField

    document.add(new IntField("id", 6, Field.Store.NO));
    

    要在修改后编写文档,它仍然是:

    indexWriter.updateDocument(new Term("pk", "<pk value>"), document);
    

    编辑: 这是一种查询包含此数字字段的方法:

    // Query <=> id <= 7
    Query query = NumericRangeQuery.newIntRange("id", Integer.MIN_VALUE, 7, true, true);
    TopDocs topDocs = indexSearcher.search(query, 10);
    

    【讨论】:

    • 所以我只使用 Integer/Float/Long/Double 对象的 toString() 值?
    • 不,所有这些字段都有一个方法numericValue(),它返回基础字段的编号。要知道数字是哪种类型(int、long...),您可以使用instanceof 或使用FieldType.NumericType
    • 我不认为这可以这样工作。如果我有查询 = new TermQuery(new Term(LUCENE_FIELD_ID, new IntField(LUCENE_FIELD_ID, 1, Store.YES).stringValue()));那么查询看起来像“id:1”,它不返回任何结果。其中 NumericUtils.intToPrefixCoded(1) 返回结果。我做错了什么?
    • 查询方式也发生了变化。现在,您应该使用NumericRangeQuery,而不是 TermQuery。
    • 谢谢。我今天也想通了。让生活更轻松。 :) 我仍然不知道如何根据“整数”更新我的文档
    【解决方案3】:

    你可以这样使用它:

    首先你必须设置FieldType的数字类型:

    FieldType TYPE_ID = new FieldType();
    ...
    TYPE_ID.setNumericType(NumericType.INT);
    TYPE_ID.freeze();
    

    然后:

    int idTerm = 10;
    BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_INT);
    NumericUtils.intToPrefixCoded(id, 0, bytes);
    Term idTerm = new Term("id", bytes);
    

    现在您可以使用idTerm 更新文档了。

    【讨论】:

      【解决方案4】:

      如果可能的话,我建议最好将 ID 存储为关键字字符串,而不是数字。如果它只是一个唯一标识符,那么将索引作为关键字更有意义。这消除了任何与数字格式混淆的需要。

      如果它实际上被用作数字,那么您可能需要手动执行更新。也就是说,搜索并获取您要更新的文档,使用tryDeleteDocument 删除旧文档,然后使用addDocument 添加更新版本。据我所知,这基本上就是 updateDocument 所做的。

      不过,第一个选项肯定是更好的方法。用作更新 ID 的非数字字段会让生活更轻松。

      【讨论】:

      • 你说得对,将键作为字符串值会很酷,但这意味着对我的代码进行重大重构并重新索引语料库,遗憾的是我没有时间。我会试试看的!
      【解决方案5】:

      根据documentation of Lucene 4.0.0,ID字段必须与StringField类一起使用:

      "被索引但未标记化的字段:整个字符串值被索引为单个标记。例如,这可能用于'国家'字段或'id'字段,或您打算用于通过字段缓存进行排序或访问的任何字段。”

      我和你有同样的问题,我通过做出这个改变解决了这个问题。之后,我的更新和删除工作完美。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多