1. 程式人生 > >lucene學習之近實時搜尋

lucene學習之近實時搜尋

下面是近實時搜尋的一個例子

public class IndexFenci {

private static String[] ids = {"1","2","3"};
private static String[] citys = {"北京","南京","上海"};
private static String[] descs = {"北京是一個美麗的城市。",
"南京是一個有文化的城市。",
"上海是一個繁華的城市。"};
private static IndexWriter writer = null;
private static SearcherManager sm =null;
private static IndexSearcher is =null;
public static void main(String[] args){
try {

Directory d = FSDirectory.open(Paths.get("D:/lucene/index"));
SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer();
IndexWriterConfig iwc = new IndexWriterConfig(analyzer);
writer = new IndexWriter(d, iwc);
TrackingIndexWriter track = new TrackingIndexWriter(writer);
track.deleteAll();
for(int i=0;i<ids.length;i++){
Document  doc = new Document();
doc.add(new StringField("city", citys[i], Field.Store.YES));
doc.add(new StringField("id", ids[i], Field.Store.YES));
doc.add(new TextField("desc",descs[i],Field.Store.YES));
track.addDocument(doc);}
System.out.println("索引:"+writer.numDocs()+"檔案");
//近實時搜尋
sm = new SearcherManager(writer, true, new SearcherFactory());
ControlledRealTimeReopenThread<IndexSearcher> crt = new ControlledRealTimeReopenThread<IndexSearcher>(track, sm, 3.0, 0.05);
crt.setDaemon(true);
crt.setName("後臺搜尋服務");
crt.start();


QueryParser parser = new QueryParser("desc",new SmartChineseAnalyzer());
Query query = parser.parse("南京城市");

Document  doc = new Document();
doc.add(new StringField("city", "杭州", Field.Store.YES));
doc.add(new StringField("id", "4", Field.Store.YES));
doc.add(new TextField("desc","杭州是一個美麗的城市",Field.Store.YES));
track.addDocument(doc);

sm.maybeRefresh();
is = sm.acquire();

TopDocs top = is.search(query, 10);
for (ScoreDoc scoreDoc:top.scoreDocs) {
Document document= is.doc(scoreDoc.doc);
System.out.print("編號:"+scoreDoc.doc);
System.out.print(" 分數: "+scoreDoc.score);
System.out.print(" id: "+document.get("id"));
System.out.print(" city: "+document.get("city"));
System.out.print(" desc: "+document.get("desc"));
System.out.println();
}

} catch (Exception e) {
e.printStackTrace();
} finally{
try {
sm.release(is);
//if(writer !=null){
//writer.close();
//}
} catch (IOException e) {
e.printStackTrace();
}
}

}
}

這樣輸出的是:

索引:3檔案
編號:1 分數: 0.27066463 id: 2 city: 南京 desc: 南京是一個有文化的城市。
編號:0 分數: 0.06074384 id: 1 city: 北京 desc: 北京是一個美麗的城市。
編號:2 分數: 0.06074384 id: 3 city: 上海 desc: 上海是一個繁華的城市。
編號:3 分數: 0.06074384 id: 4 city: 杭州 desc: 杭州是一個美麗的城市

但是杭州這條索引資訊還沒有存到本地。用下面的程式去搜索:

public class SearcherFenci {
public static IndexSearcher is =null;
public static IndexReader indexReader = null;
public static void main(String[] args) throws IOException {

SearcherFenci searcherFenci = new SearcherFenci();
searcherFenci.displayAllTokenInfo("南京城市");

}


/**
* 得到分詞的結果
*/
public  void displayAllTokenInfo(String str){
try {
Directory d = FSDirectory.open(Paths.get("D:/lucene/index"));
indexReader = DirectoryReader.open(d);
System.out.println("maxdoc: "+indexReader.maxDoc());
System.out.println("numdoc: "+indexReader.numDocs());
System.out.println("numdeletedoc: "+indexReader.numDeletedDocs());
SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer();
IndexSearcher is = new IndexSearcher(indexReader);
QueryParser queryParser = new QueryParser("desc", analyzer);
Query query = queryParser.parse(str);
TopDocs top = is.search(query, 10);

for(ScoreDoc scoreDoc : top.scoreDocs){
Document doc = is.doc(scoreDoc.doc);
System.out.print("編號:"+scoreDoc.doc);
System.out.print(" 分數: "+scoreDoc.score);
System.out.print(" id: "+doc.get("id"));
System.out.print(" city: "+doc.get("city"));
System.out.print(" desc: "+doc.get("desc"));
System.out.println();
}
indexReader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

輸出的結果是:

maxdoc: 3
numdoc: 3
numdeletedoc: 0
編號:1 分數: 0.5908754 id: 2 city: 南京 desc: 南京是一個有文化的城市。
編號:0 分數: 0.06037879 id: 1 city: 北京 desc: 北京是一個美麗的城市。
編號:2 分數: 0.06037879 id: 3 city: 上海 desc: 上海是一個繁華的城市。

杭州沒在本地索引中,因為還沒提交。這樣就是近實時索引的內容了。可以搜尋到還沒提交的修改資訊。