欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

lucene-对多个索引的搜索和多线程搜索

程序员文章站 2022-05-15 16:13:48
...

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

}

}