lucene4之后的近实时搜索实现

时间:2023-03-09 17:36:38
lucene4之后的近实时搜索实现

好久没干这块东西了,近几天须要做这个。所以又一次学了一下。首先很感谢孔浩老师,没孔浩老师的视频我也不会进入lucene的殿堂。

老师当时讲的实时搜索还是NRTManager,如今已经都变了,这个类已经不存在了,在4.0之后消失的。到我如今使用的5.2.1都是以下的方法:

首先罗列会使用的特殊类(经常使用的不再赘述):

TrackingIndexWriter  追踪writer,在api中有介绍,仅仅有通过这个类进行更新ControlledRealTimeReopenThread才干获得更新

ControlledRealTimeReopenThread  实时搜索事实上叫做“近实时搜索”。就是当更新之后在非常短时间内进行了更新然后让人感觉不出来,这样说来就须要一个守护线程去坚守这个过程,当更新的时候就去获取更新然后通知查询更新了,这样“近实时搜索”就实现了,这个类就是这个守护线程。

我写了个測试在以下,里面不懂得能够查看api。也有部分凝视,希望对大家有帮助。

package com.xikoubuy.main;





import java.io.IOException;





import org.apache.lucene.analysis.Analyzer;

import org.apache.lucene.document.Document;

import org.apache.lucene.document.Field;

import org.apache.lucene.document.TextField;

import org.apache.lucene.index.IndexWriter;

import org.apache.lucene.index.IndexWriterConfig;

import org.apache.lucene.index.TrackingIndexWriter;

import org.apache.lucene.queryparser.classic.ParseException;

import org.apache.lucene.queryparser.classic.QueryParser;

import org.apache.lucene.search.ControlledRealTimeReopenThread;

import org.apache.lucene.search.IndexSearcher;

import org.apache.lucene.search.Query;

import org.apache.lucene.search.ReferenceManager;

import org.apache.lucene.search.ScoreDoc;

import org.apache.lucene.search.SearcherFactory;

import org.apache.lucene.search.SearcherManager;

import org.apache.lucene.store.Directory;

import org.apache.lucene.store.RAMDirectory;

import org.wltea.analyzer.lucene.IKAnalyzer;





public class NRTTest {





private Directory directory;

private Analyzer analyzer;

////追踪writer。这样才干在更新之后通知搜索

private TrackingIndexWriter writer;

//是线程安全的.第二个參数是是否在全部缓存清空后让search看到

private SearcherManager searcherManager;

private IndexSearcher searcher;



public static void main(String[] args) throws IOException {



new NRTTest();

}





public NRTTest() throws IOException {

directory = new RAMDirectory();

analyzer = new IKAnalyzer(true);

IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);

IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);

writer = new TrackingIndexWriter(indexWriter);

searcherManager = new SearcherManager(indexWriter, true, new SearcherFactory());

ControlledRealTimeReopenThread CRTReopenThead = new ControlledRealTimeReopenThread(writer, searcherManager, 5.0, 0.025);

//守护线程,又叫后台线程,级别比較低,假设没有主线程这个也会消失,这个线程作用就是定期更新让searchManager管理的search能获得更新

CRTReopenThead.setDaemon(true);

CRTReopenThead.setName("更新线程");

CRTReopenThead.start();

this.addDoc();

this.searchDoc();

}



public synchronized void addDoc(){

final int i = 0;

new Thread(){



public  void run() {

while(true){

try {

Thread.sleep(10000);

System.out.println("----增加文档中");

Document doc = new Document();

doc.add(new Field("title", "标题" + i, TextField.TYPE_STORED));

doc.add(new Field("content", "我爱你中国" + i, TextField.TYPE_STORED));

writer.addDocument(doc);



} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

};

}.start();

}



public synchronized void searchDoc(){

new Thread(){

public void run() {

while(true){

try {

Thread.sleep(5000);

System.out.println("----检索中");

searcher = searcherManager.acquire();

QueryParser parser = new QueryParser("content", analyzer);

Query query = parser.parse("中国");

ScoreDoc [] hits = searcher.search(query, 100).scoreDocs;

for(int i = 0; i < hits.length;i++){

Document doc = searcher.doc(hits[i].doc );

System.out.println(doc.get("title") + hits[i].doc);

}

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (ParseException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

finally{

try {

searcherManager.release(searcher);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

searcher = null;

}

};

}.start();

}





}