最近在使用lucene更新索引时出现了lucene并不是删除原来的记录再重新创建,而是又直接新建了一条记录,导致搜索出来的结果完全不正确。由于之前使用过lucene的索引更新并没有此问题,最近因为需要根据ID排序,因此创建document时将myCardID改成NumericField类型,难道是这个问题引起的?新增一个Field保存ID的值,并修改更新索引Term的域,重新跑过lucene后,问题解决。
为何使用数字类型的Field后lucene更新索引时会失败呢?
《Lucene实战》提到:如果需要通过Term类删除单个文档,需要确认在每个文档中都已索引过对应的Field类,还需要确认所有域值都是唯一的,这样才能将这个文档单独找出来删除。你可以对这个域进行任意命名(通常用ID命名),该域需要被索引成未被分析的域以保证分析器不会将它分解成语汇单元。
更新索引失败时的代码片段
/**
* 更新索引
*
* @param task
* @throws Exception
*/
public void updateIndex(PersonalCard task) throws Exception {
Term term = new Term("myCardID", task.getMyCardID()+ "");
Document doc = getDocument(task);
writer.updateDocument(term, doc);
closeIndex();
}
/**
* 创建文档
*
* @return Document lucene文档
* @throws Exception
*/
protected Document getDocument(PersonalCard task) throws Exception {
Document doc = new Document();
doc.add(new NumericField("myCardID",Field.Store.YES,true).setLongValue(task.getMyCardID()));
//......
return doc;
}
修改后的代码片段
/**
* 更新索引
*
* @param task
* @throws Exception
*/
public void updateIndex(PersonalCard task) throws Exception {
Term term = new Term("cardID", task.getMyCardID()+"");
Document doc = getDocument(task);
writer.updateDocument(term, doc);
closeIndex();
}
/**
* 创建文档
*
* @return Document lucene文档
* @throws Exception
*/
protected Document getDocument(PersonalCard task) throws Exception {
Document doc = new Document();
doc.add(new NumericField("myCardID",Field.Store.YES,true).setLongValue(task.getMyCardID()));
doc.add(new Field("cardID",task.getMyCardID() + "", Field.Store.YES,Field.Index.NOT_ANALYZED));
//......
return doc;
}