lucene-对多个索引的搜索和多线程搜索
1、如果应用程序架构由多个LUCENE索引组成,则可以通过MutltiSearcher把所有索引搜索。也可以通过ParallelMultiSearcher进行多线程搜索。在单核的情况下,MultiSearcher比ParallelMultiSearcher性能更高。
2、MultiSearcher
搜索2个搜索,把动物按首字母在字母表中的位置分成2部分,一部分一个索引
public class MultisearcherTest extends TestCase{
private Indexsearcher[]searchers;
public void setUp() throwsException{
String[] animals={"aardvark","beaver","coati","dog","lemur",
"python","vicuna","zebra"};
Ananlyzer analyzer=ne WhitespaceAnalyzer();
Directory aTomDirectory =new RAMDirectory();
Directory nTOzDirectory=new RAMDirectory();
//建立2个索引
IndexWriteraTomwriter=new IndexWriter(atomDirectory,analyzer,true);
IndexWriternTozwriter=new IndexWriter(aTozDirectory,analyzer,true);
for(int i=0;i<anaimals.length;i+){
Document doc=new Document();
Stringanimal=animals[i];
doc.add(Filed.Keyword("animal",animal));
if (animal.compareToIgnoreCase("n")<0){
aTomWriter.addDocument(doc);//前半部分索引a-m
}else{
nTozWriter.addDocument(doc);//后半部分索引 n-z
}
}
aTomwriter.close();
nTozwriter.close();
searchers=newIndexsearcher[2];
searcher[0]=new IndexSearcher(aTOmDirectory);
searcher[1]=new IndexSearhcer(nTOzDirectory);
}
public void testMulti() throws Exception{
MultiSearcher searcher=new MultiSearcher(searchers);
//对2个索引进行搜索
Query query=new RangeQuery(new Term("animal","h"),newTerm("animal","t"),true);
Hits hits= searcher.search(query);
}
}
3、ParallelMultiSearcher多线程搜索
搜索操作为每个Searchable分配一个线程,直到所有线程都完成其搜索。基本搜索和进行过滤的搜索是并行执行的。
lucene通过RMI为用户提供搜索远程索引功能。
RMI服务器绑定了一个RemoteSearchable的实例,它和IndexSearcher、MultiSearch一样,实现Searchable接口
1)把文档按26个字母切分为26个索引。服务器端向客户端提供2个RMI调用
public class SearchServer{
privatestatic final String ALPHABET="abcdefghijklmnopqrstuvwxyz";
publicstatic void main(String[] args) throws Exceptino{
if (args.length!=1){
System.err.printLn("Usage:Searchserver<basedir>");
System.exit(-1);
}
String basedir=args[0];
//为每个索引建立一个IndexSearcher对象
Searchable[] searchables=new Searchable[ALPHABET.length()];
for (int i=0;i<ALPHABET.length;i++){
searchables[]=new IndexSearcher(newFile(basedir,""+ALPHABET.charAt(i)).getAbsolutePath());
}
//注册可供客户端调用服务的端口
LocateRegistry.createRegistry(1099);
//使用multiSearcher完成所有索引的搜索
SearchermultiSearcher=new MultiSearcher(searchables);
RemoteSearchablemultiImpl=new RemoteSearchables(multiSearcher);
Naming.rebind("//localhost/LIA_Multi",multiImpl);//注册RMI方法
//使用parallelSearcher完成搜索
Searcher parallelSearcher=newParallelMultiSearcher(searchables);
RemoteSearchableparallelImpl=new RemoteSearchables(parallelSearcher);
Naming.rebind("//localhost/LIA_Parallel",parallelImpl);//注册RMI方法
System.out.println("server started");
}
}
2)客户端
public class SearchClient{
private static HashMapsearchercache=new HashMap();
public static voidmain(String[] args) throws Exception{
if (args.length!=1){
System.err.println("Usage:SearchClient<query>");
System.exit(-1);
}
Stringword=args[0];
for (int i=0;i<5;i++){
search("LIA_Multi",word);//调用服务器的multi方法搜索
search("LIA_Multi",word);//调用服务器的multi方法搜索
}
}
private static void search(String name,Stringword) throws Exception{
TermQuery query=new TermQuery(new Term("word",word));
MultiSearcher searcher=(MultiSearcher)searcherCache.get(name);//检查缓存中是否有该搜索器,该搜索器是带缓存功能的
if (searcher==null){//没有该搜索,则生成新的搜索
searcher=new MultiSearcher(newSearchable[]{lookupRemote(name)});
searcherCache.put(name,searcher);
}
//统计时间
long begin=new Date().getTime();
Hits hits=searcher.search(query);
long end=new Date().getTime()
...........
...........
//不要关闭searcher对象
}
private static Searchable lookupRemote(Stringname) throws Exception{
return (Searchable) Naming.lookup("//localhost/"+name);
}
}
上一篇: 08.Java 基础 - 反射