Lucene5学习之多索引目录查询以及多线程查询

标签: lucene5 学习 多索 | 发表时间:2015-03-29 21:09 | 作者:
出处:http://www.iteye.com

     上一篇中我们使用多线程创建了索引,下面我们来试着采用不把多个索引目录里的数据合并到一个新的索引目录的方式去查询索引数据,当然你也可以合并(合并到一个索引目录查询就很简单了),其实很多情况我们都是不合并到一个索引目录的,那多索引目录该如何查询呢,在Lucene5中使用的MultiReader类,在Lucene4时代,使用的是MultiSearcher类。至于Lucene多线程查询,只需要在构建IndexSearcher对象时传入一个ExecutorService线程池管理对象即可,具体请看下面贴出的示例代码:

package com.yida.framework.lucene5.index;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.store.Directory;

import com.yida.framework.lucene5.util.LuceneUtils;

/**
 * 多线程多索引目录查询测试
 * @author Lanxiaowei
 *
 */
public class MultiThreadSearchTest {
	public static void main(String[] args) throws InterruptedException, ExecutionException, IOException {
		//每个线程都从5个索引目录中查询,所以最终5个线程的查询结果都一样
		//multiThreadAndMultiReaderSearch();
		
		//多索引目录查询(把多个索引目录当作一个索引目录)
		multiReaderSearch();
	}
	
	/**
	 * 多索引目录查询
	 * @throws InterruptedException
	 * @throws ExecutionException
	 * @throws IOException
	 */
	public static void multiReaderSearch()  throws InterruptedException, ExecutionException, IOException {
		Directory directory1 = LuceneUtils.openFSDirectory("C:/lucenedir1");
		Directory directory2 = LuceneUtils.openFSDirectory("C:/lucenedir2");
		Directory directory3 = LuceneUtils.openFSDirectory("C:/lucenedir3");
		Directory directory4 = LuceneUtils.openFSDirectory("C:/lucenedir4");
		Directory directory5 = LuceneUtils.openFSDirectory("C:/lucenedir5");
		IndexReader reader1 = DirectoryReader.open(directory1);
		IndexReader reader2 = DirectoryReader.open(directory2);
		IndexReader reader3 = DirectoryReader.open(directory3);
		IndexReader reader4 = DirectoryReader.open(directory4);
		IndexReader reader5 = DirectoryReader.open(directory5);
		MultiReader multiReader = new MultiReader(reader1,reader2,reader3,reader4,reader5);
		
		IndexSearcher indexSearcher = LuceneUtils.getIndexSearcher(multiReader);
		Query query = new TermQuery(new Term("contents","volatile"));
		List<Document> list = LuceneUtils.query(indexSearcher, query);
		if(null == list || list.size() <= 0) {
			System.out.println("No results.");
			return;
		}
		for(Document doc : list) {
			String path = doc.get("path");
			//String content = doc.get("contents");
			System.out.println("path:" + path);
			//System.out.println("contents:" + content);
		}
	}
	
	/**
	 * 多索引目录且多线程查询,异步收集查询结果
	 * @throws InterruptedException
	 * @throws ExecutionException
	 * @throws IOException
	 */
	public static void multiThreadAndMultiReaderSearch()  throws InterruptedException, ExecutionException, IOException {
		int count = 5;
		ExecutorService pool = Executors.newFixedThreadPool(count);
		
		Directory directory1 = LuceneUtils.openFSDirectory("C:/lucenedir1");
		Directory directory2 = LuceneUtils.openFSDirectory("C:/lucenedir2");
		Directory directory3 = LuceneUtils.openFSDirectory("C:/lucenedir3");
		Directory directory4 = LuceneUtils.openFSDirectory("C:/lucenedir4");
		Directory directory5 = LuceneUtils.openFSDirectory("C:/lucenedir5");
		IndexReader reader1 = DirectoryReader.open(directory1);
		IndexReader reader2 = DirectoryReader.open(directory2);
		IndexReader reader3 = DirectoryReader.open(directory3);
		IndexReader reader4 = DirectoryReader.open(directory4);
		IndexReader reader5 = DirectoryReader.open(directory5);
		MultiReader multiReader = new MultiReader(reader1,reader2,reader3,reader4,reader5);
		
		final IndexSearcher indexSearcher = LuceneUtils.getIndexSearcher(multiReader, pool);
		final Query query = new TermQuery(new Term("contents","volatile"));
		List<Future<List<Document>>> futures = new ArrayList<Future<List<Document>>>(count);
		for (int i = 0; i < count; i++) {
			futures.add(pool.submit(new Callable<List<Document>>() {
				public List<Document> call() throws Exception {
					return LuceneUtils.query(indexSearcher, query);
				}
			}));
		}
		
		int t = 0;
		//通过Future异步获取线程执行后返回的结果
		for (Future<List<Document>> future : futures) {
			List<Document> list = future.get();
			if(null == list || list.size() <= 0) {
				t++;
				continue;
			}
			for(Document doc : list) {
				String path = doc.get("path");
				//String content = doc.get("contents");
				System.out.println("path:" + path);
				//System.out.println("contents:" + content);
			}
			System.out.println("");
		}
		//释放线程池资源
		pool.shutdown();
		
		if(t == count) {
			System.out.println("No results.");
		}
	}
}

当然你也可以把上面的代码改造成每个线程查询一个索引目录,我上面是每个线程都从5个索引目录中查询,所以结果会打印5次,看到运行结果请不要感到奇怪。

 

如果你还有什么问题请加我Q-Q:7-3-6-0-3-1-3-0-5,

或者加裙
一起交流学习!



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [lucene5 学习 多索] 推荐:

Lucene5学习之多索引目录查询以及多线程查询

- - ITeye博客
     上一篇中我们使用多线程创建了索引,下面我们来试着采用不把多个索引目录里的数据合并到一个新的索引目录的方式去查询索引数据,当然你也可以合并(合并到一个索引目录查询就很简单了),其实很多情况我们都是不合并到一个索引目录的,那多索引目录该如何查询呢,在Lucene5中使用的MultiReader类,在Lucene4时代,使用的是MultiSearcher类.

Lucene5学习之Suggest关键字提示

- - 编程语言 - ITeye博客
         首先需要搞清楚Suggest模块是用来解决什么问题的. Google我想大家都用过,当我们在搜索输入框里输入搜索关键字的时候,紧贴着输入框下方会弹出一个提示框,提示框里会列出Top N个包含当前用户输入的搜索关键字的搜索热词,如图:. 在Lucene中,这种搜索关键字自动提示功能是由Suggest模块提供的.

Lucene5学习之SpellCheck拼写纠错

- - ITeye博客
        最近有点累,让这篇又姗姗来迟了,各位不好意思,让你们久等了. 趁着周末一个人没什么事,继续Lucene5系列的脚步,今天主题是Suggest模块下另一个功能:拼写纠错. 大家还是看图吧,这样会比较形象:.        看完上面两张图片,我想大家应该已经知道SpellCheck是用来解决问题的了吧.

Lucene5学习之Group分组统计

- - ITeye博客
        Group即分组,类似SQL里的group by功能,Lucene中分组是通过内置的几种Collector结果集收集器实现的,有关group的结果集收集器都在org.apache.lucene.search.grouping包及其子包下,.  包含group关键字的Collector都是有关Group分组的结果收集器,如果你只需要统计如下这些分组信息:.

Lucene5学习之多线程创建索引

- - 编程语言 - ITeye博客
    昨晚睡觉前把多线程创建索引demo写好了,今天早上7点多就起来,趁着劲头赶紧记录分享一下,这样对那些同样对Lucene感兴趣的童鞋也有所帮助.     我们都知道Lucene的IndexWriter在构造初始化的时候会去获取索引目录的写锁writerLock,加锁的目的就是保证同时只能有一个IndexWriter实例在往索引目录中写数据,具体看截图:.

iptables NAT 学习

- - BlogJava-首页技术区
为了搞清楚iptables NAT的过程,做了这个实验. 使用了1台双网卡服务器和1台单网卡服务器,2个网段. 1.       为了看到调度服务器上的数据转发过程,首先在调度服务器上分出内核的debug日志:. l 在/etc/rsyslog.conf最后增加:kern.debug /var/log/iptables.log.

Servlet Filter 学习

- - CSDN博客架构设计推荐文章
最近在研究CAS , CAS 中的Servlet Filter 不太熟悉, 所以花了点时间学下了下这部分的知识, 分成以下几部分 学习. Servlet Filter  的功能和用法. Servlet Filter 顺序的注意事项. A filter is an object that performs filtering tasks on either the request to a resource (a servlet or static content), or on the response from a resource, or both.

mongo 学习

- - CSDN博客系统运维推荐文章
mongod 启动参数详解:. master 启动: ./mongod --dbpath /data/db/master --logpath /data/db/master.log --logappend  --fork --port 2717 --master --oplogSize 64 . slave 启动: ./mongod  --dbpath /data/db/slave  --logpath  /data/db/slaver.log --logappend  --fork  -port 27018  --slave --slavedelay 5 --autoresync --source localhost:27017  .

pushlet 学习

- - 企业架构 - ITeye博客
转自: http://blog.csdn.net/houpengfei111/article/details/7498481.     pushlet是一种comet实现,在servlet机制下,数据从server端的java对象直接推送(push)到(动态)HTML页面,而无需任何java applet或者插件的帮助.

Storm Trident 学习

- - 小火箭
Storm支持的三种语义:. 至少一次语义的Topology写法. 参考资料: Storm消息的可靠性保障 Storm提供了Acker的机制来保证数据至少被处理一次,是由编程人员决定是否使用这一特性,要使用这一特性需要:. 在Spout emit时添加一个MsgID,那么ack和fail方法将会被调用当Tuple被正确地处理了或发生了错误.