2012-12-19 75 views
1

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

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

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

+0

你有什么用NumericUtils人工改造的数字,而不是使用特定的原因[NumericField(http://lucene.apache.org/core/3_6_0 /api/all/org/apache/lucene/document/NumericField.html)? – femtoRgon

+0

那么因为IndexWriter想要一个术语,而我不知道其他方式来创建一个数字字段的术语 –

回答

0

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

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

不过,第一种选择当然是更好的方法。用作更新ID的非数字字段会使生活更轻松。

+0

您有权将键作为字符串值很酷,但这意味着整个代码中的重大重构以及重新索引语料库,为此我可惜没有时间。我会试一下! –

1

使用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); 
+0

因此,我只是使用Integer/Float/Long/Double对象的toString()值? –

+0

不,所有这些字段都有一个方法[numericValue()](http://lucene.apache.org/core/4_0_0/core/org/apache/lucene/document/Field.html#numericValue()),它返回底层字段的编号。要知道数字的类型(int,long ...),可以使用'instanceof'或使用[FieldType.NumericType](http://lucene.apache.org/core/4_0_0/core/org/apache/ lucene/document/FieldType.NumericType.html) – aymeric

+0

我不认为这可以这样工作。如果我有query = new TermQuery(新术语(LUCENE_FIELD_ID,new IntField(LUCENE_FIELD_ID,1,Store.YES).stringValue()));那么查询看起来像“id:1”,它不会返回任何结果。 NumericUtils.intToPrefixCoded(1)返回结果。我究竟做错了什么? –

0

你可以用这种方式:

首先,你必须设置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更新文档。

0

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

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

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

0

随着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);