Lucene中关于操作索引即时生效的探讨

 一、引出问题,抛砖引玉
    在Lucene中IndexWriter操作索引后,IndexReader必须重新打开索引才能使刚刚操作的数据生效。而在这个重新打开过程的一瞬间会影响整个查询的。我不知道大家在项目中是怎么去操作的,以下我将我的方法与大家分享,希望能够起到抛砖引玉的效果。


二、范例Demo

public void testLuceSynchronze() throws IOException{
	    String NAME_FIELD = "_name";
		File f = new File("log/index/testLucene");
		if(!f.isDirectory())
			f.mkdirs();
		Directory directory = FSDirectory.getDirectory(f);
		IndexWriter write = new IndexWriter(directory, false, new StandardAnalyzer());
		//写索引文件,标记为"位置一"
		Field nameField1 = new Field(NAME_FIELD,"张三",Store.YES,Index.UN_TOKENIZED);
		Field nameField2 = new Field(NAME_FIELD,"张四",Store.YES,Index.UN_TOKENIZED);
		List<Field> listFields = new ArrayList<Field>();
		listFields.add(nameField1);
		listFields.add(nameField2);
		
		for(Field field : listFields){
			Document doc = new Document();
			doc.add(field);
			write.addDocument(doc);
		}
		write.optimize();
		write.close();
		
		log.info("写索引完毕!");
	
		//以下方法构建查询Query,标记为"位置二"
		IndexSearcher searcher = new IndexSearcher(directory);
		Query tq = new PrefixQuery(new Term(NAME_FIELD,"张"));
		Hits hits = searcher.search(tq);
		if(hits.length() == 0){
			log.info("查无此人!");
		}else{
			for(int i=0;i<hits.length();i++){
				Document ret = hits.doc(i);
				String name = ret.getField(NAME_FIELD).stringValue();
				log.info(name);
			}
		}
		searcher.close();
	}

 
运行程序,控制台输入:

0    [main] INFO  test.lucene.TestSynchronize  - 写索引完毕!
78   [main] INFO  test.lucene.TestSynchronize  - 张三
78   [main] INFO  test.lucene.TestSynchronize  - 张四

以上是在位置二处构建IndexSearcher的,如果移至位置一处,就不会有查询到的记录。找到Lucene的文档,发现有这么一段说明。

 

Regardless of autoCommit, an IndexReader or IndexSearcher will only see the index as of the "point in time" that it was opened. Any changes committed to the index after the reader was opened are not visible until the reader is re-opened.

三、我的解决方案:

1)IndexWriter和IndexSearcher共用同一个Directory

2)IndexWriter或IndexReader对索引有操作的话,更改boolean的值,重新构建IndexSeacher,注意同步一下getSearcher()

	protected synchronized IndexSearcher getSearcher() {
		if(needFreshSearcher){
			this.needFreshSearcher = false;
			try {
				this.searcher.close();
				this.searcher = new IndexSearcher(getDirectory());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return searcher;
	}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值