Lucene4.10使用教程(四):lucene的Search
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.ByteOrderMark;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeFilter;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.Version;
/**
* 對於中文來說,Lucene提供的search基本上不能使用,使用中文分詞器替換即可
* @author Johnny
*
*/
public class SearchUtil {
private Version Lucene_Version = Version.LUCENE_4_10_2;
private Directory directory;
private DirectoryReader reader = null;
private String[] ids = {"1","2","3","4","5","6"};
private String[] emails = {"
private String[] contents = {
"welcome to visited the space,I like book java",
"hello boy, I like pingpeng ball",
"my name is cc I like game java",
"I like football",
"I like football and I like basketball too",
"I like movie and swim java"
};
private Date[] dates = null;
private int[] attachs = {2,3,1,4,5,5};
private String[] names = {"zhangsan","lisi","john","jetty","mike","jake"};
public SearchUtil() {
// directory = new RAMDirectory();
try {
directory = FSDirectory.open(new File("/Users/ChinaMWorld/Desktop/index/"));
setDates();
} catch (IOException e) {
e.printStackTrace();
}
}
private void setDates() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
dates = new Date[ids.length];
dates[0] = sdf.parse("2010-02-19");
dates[1] = sdf.parse("2012-01-11");
dates[2] = sdf.parse("2011-09-19");
dates[3] = sdf.parse("2010-12-22");
dates[4] = sdf.parse("2012-01-01");
dates[5] = sdf.parse("2011-05-19");
} catch (ParseException e) {
e.printStackTrace();
}
}
public void index() {
IndexWriter writer = null;
try {
writer = new IndexWriter(directory,new IndexWriterConfig(Lucene_Version, new StandardAnalyzer()));
//writer.deleteAll();
Document doc = null;
for(int i=0;i<ids.length;i++) {
doc = new Document();
doc.add(new StringField("id",ids[i],Store.YES));
doc.add(new StringField("email", emails[i],Store.YES));
doc.add(new TextField("content", contents[i], Store.NO));
doc.add(new StringField("name",names[i], Store.YES));
//儲存數字
doc.add(new IntField("attach",attachs[i], Store.YES));
//儲存日期
doc.add(new LongField("date", dates[i].getTime(), Store.YES));
String et = emails[i].substring(emails[i].lastIndexOf("@")+1);
System.out.println(et);
/**
* 在Lucene4.x中,只能給域加權,部門給文件加權,如果要提高文件的加權,需要給
* 文件的每個域進行加權
* **/
writer.addDocument(doc);
}
} catch (IOException e) {
e.printStackTrace();
} finally{
try{
if(writer!=null) writer.close();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
public IndexSearcher getSearcher() {
try {
if(reader==null) {
reader = DirectoryReader.open(directory);
} else {
DirectoryReader tr = DirectoryReader.openIfChanged(reader) ;
if(tr!=null) {
reader.close();
reader = tr;
}
}
return new IndexSearcher(reader);
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 指定field進行查詢,termquery不能進行數字和日期的查詢
* 日期的查詢需要轉成數字進行查詢,
* 數字查詢使用NumbericRangeQuery
* @param field
* @param name
* @param num
*/
public void searchByTerm(String field,String name,int num) {
try {
IndexSearcher searcher = getSearcher();
Query query = new TermQuery(new Term(field,name));
TopDocs tds = searcher.search(query, num);
System.out.println("一共查詢了:"+tds.totalHits);
for(ScoreDoc sd:tds.scoreDocs) {
Document doc = searcher.doc(sd.doc);
System.out.println(doc.get("id")+"---->"+
doc.get("name")+"["+doc.get("email")+"]-->"+doc.get("id")+","+
doc.get("attach")+","+doc.get("date"));
}
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void searchByTermRange(String field,String start,String end,int num) {
try {
IndexSearcher searcher = getSearcher();
Query query = new TermRangeQuery(field,new BytesRef(start.getBytes()),new BytesRef(end.getBytes()) , true, true);
TopDocs tds = searcher.search(query, num);
System.out.println("一共查詢了:"+tds.totalHits);
for(ScoreDoc sd:tds.scoreDocs) {
Document doc = searcher.doc(sd.doc);
System.out.println(doc.get("id")+"---->"+
doc.get("name")+"["+doc.get("email")+"]-->"+doc.get("id")+","+
doc.get("attach")+","+doc.get("date"));
}
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void searchByQueryParse(Query query,int num) {
try {
IndexSearcher searcher = getSearcher();
TopDocs tds = searcher.search(query, num);
System.out.println("一共查詢了:"+tds.totalHits);
for(ScoreDoc sd:tds.scoreDocs) {
Document doc = searcher.doc(sd.doc);
System.out.println(doc.get("id")+"---->"+
doc.get("name")+"["+doc.get("email")+"]-->"+doc.get("id")+","+
doc.get("attach")+","+doc.get("date")+"=="+sd.score);
}
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/***如果想要獲取為儲存到索引中得值,可以根據ID去原始檔中進行查詢並返回**/
public void searchPage(String query,int pageIndex,int pageSize) {
try {
IndexSearcher searcher = getSearcher();
QueryParser parser = new QueryParser("content",new StandardAnalyzer());
Query q =null;
try {
q = parser.parse(query);
} catch (org.apache.lucene.queryparser.classic.ParseException e) {
e.printStackTrace();
}
TopDocs tds = searcher.search(q, 500);
ScoreDoc[] sds = tds.scoreDocs;
int start = (pageIndex-1)*pageSize;
int end = pageIndex*pageSize;
if(end>=sds.length) end = sds.length;
for(int i=start;i<end;i++) {
Document doc = searcher.doc(sds[i].doc);
String id = doc.get("id");
int arrInt = -1;
for(int j=0;j<ids.length;j++){
if(id.equals(ids[j])){
arrInt = j;
break;
}
}
System.out.println(sds[i].doc+":"+doc.get("name")+"-->"+contents[arrInt]);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根據頁碼和分頁大小獲取上一次的最後一個ScoreDoc
*/
private ScoreDoc getLastScoreDoc(int pageIndex,int pageSize,Query query,IndexSearcher searcher) throws IOException {
if(pageIndex==1)return null;//如果是第一頁就返回空
int num = pageSize*(pageIndex-1);//獲取上一頁的數量
TopDocs tds = searcher.search(query, num);
return tds.scoreDocs[num-1];
}
/***
* 在使用時,searchAfter查詢的是指定頁數後面的資料,效率更高,推薦使用
* @param query
* @param pageIndex
* @param pageSize
*/
public void searchPageByAfter(String query,int pageIndex,int pageSize) {
try {
IndexSearcher searcher = getSearcher();
QueryParser parser = new QueryParser("content",new StandardAnalyzer());
Query q = null;
try {
q = parser.parse(query);
} catch (org.apache.lucene.queryparser.classic.ParseException e) {
e.printStackTrace();
}
//先獲取上一頁的最後一個元素
ScoreDoc lastSd = getLastScoreDoc(pageIndex, pageSize, q, searcher);
//通過最後一個元素搜尋下頁的pageSize個元素
TopDocs tds = searcher.searchAfter(lastSd,q, pageSize);
for(ScoreDoc sd:tds.scoreDocs) {
Document doc = searcher.doc(sd.doc);
String id = doc.get("id");
int arrInt = -1;
for(int j=0;j<ids.length;j++){
if(id.equals(ids[j])){
arrInt = j;
break;
}
}
System.out.println(doc.get("name")+"-->"+contents[arrInt]);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
測試程式碼如下:
相關推薦
Lucene4.10使用教程(四):lucene的Search
package com.johnny.lucene02.search; import java.io.File; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; im
Spring Cloud 入門教程(四): 分布式環境下自動發現配置服務
.html article png discover ice conf label tail 註釋 前一章, 我們的Hello world應用服務,通過配置服務器Config Server獲取到了我們配置的hello信息“hello world”. 但自己的配置文件中必須配
Spring Boot系列教程四:配置文件詳解properties
date int ava ota axu return 端口 rand work 一.配置隨機數,使用隨機數 在application.properties文件添加配置信息 1 #32位隨機數 2 woniu.secret=${random.value} 3 #隨機整數
Shiro學習系列教程四:集成web(二)
shiro學習 凱哥java 本講主要內容:1:shiro對訪問URL可使用通配符進行匹配2:shiro標簽的使用3:shiro會話的機制URL匹配方式:演示:現在shiro.ini配置的路徑為:直接訪問/adminOk.沒問題。那麽我們訪問/admin1呢?就不行了。修改shiro.ini配置文件。
Spring Security教程(四):自定義登入頁
在前面的例子中,登陸頁面都是用的Spring Security自己提供的,這明顯不符合實際開發場景,同時也沒有退出和登出按鈕,因此在每次測試的時候都要通過關閉瀏覽器來登出達到清除session的效果。 一、自定義頁面 login.jsp: <%@ page language="
Java開發公眾號系列教程(四):公眾號訊息推送|事件訊息|模板訊息應用
今天分享一下公眾號推送模板訊息的開發案例。應用場景:使用者在公眾號上進行了一些操作後,公眾號自動向使用者推送相關的模板訊息,常見的比如使用者在公眾號付款後會收到商家的付款訊息提醒。接下來通過筆者在測試賬戶上的開發案例,效果如下: &nb
Spring Boot基礎教程 ( 四 ) :Spring Boot 屬性配置檔案詳解
相信很多人選擇Spring Boot主要是考慮到它既能兼顧Spring的強大功能,還能實現快速開發的便捷。我們在Spring Boot使用過程中,最直觀的感受就是沒有了原來自己整合Spring應用時繁多的XML配置內容,替代它的是在pom.xml中引入模組化的Starter
Quartz教程四:Trigger
原文連結 | 譯文連結 | 翻譯:nkcoder 本系列教程由quartz-2.2.x官方文件翻譯、整理而來,希望給同樣對quartz感興趣的朋友一些參考和幫助,有任何不當或錯誤之處,歡迎指正;有興趣研究原始碼的同學,可以參考我對quartz-core原始碼的註釋(進行中)。 與job一樣,t
PostGIS教程四:載入空間資料
在各種庫和應用程式的支援下,PostGIS提供了許多用於載入資料的選項。 本節將重點介紹使用PostGIS shapefile載入工具載入shapefile的基礎知識。 一、PostGIS s
熊大UWB系列教程四:UWB超寬頻三基站定位系統原理介紹與效果展示
對超寬頻感興趣的朋友,請關注熊大的微信公眾號,熊大將在上面釋出超寬頻教程,行業資訊,技術應用。幫助你更好的瞭解、學習、使用超寬頻技術。 購買熊大超寬頻系統,會提供微控制器原始碼,上位機原始碼還有技術支援。 熊大最近忙於開發超寬頻多基站多標籤定
MVC教程四:Controller向View傳值的幾種方式
一、通過ViewData傳值 MVC從開始版本就一直支援使用ViewData將Controller裡面的資料傳遞到View。ViewData定義如下: 從上面的截圖中可以看出,ViewData裡面存的是字典型別的資料,在檢視ViewDataDictionary的定義: 注意:ViewDataDi
教你如何開發VR遊戲系列教程四:UI 設計
這篇帖子主要介紹怎麼建立VR UI。 常見形式:1、2D NGUI、UGUI2、3D模型由於後續NGUI可能停止更新以及與U3d後續版本不相容問題,那麼主要就以UGUI為例。NGUI簡單說說。3D模型的話沒什麼好說,就跟普通VR場景一樣設定。2DUI,可以兩個螢幕都顯示
【QT】QT從零入門教程(四):選單欄、工具欄、狀態列
選單欄、工具欄、工作列是軟體中常見的元件,本節將會講解如何建立選單欄並生成一級選單、二級選單,如何在工具欄中新增圖示和控制元件,如何在工作列中顯示文字。 標題及圖示 // 標題大小 setWindowTitle("影象處理自編軟體 by
Google Map API Version3 教程(四):給marker標記加上自定義內容
lat = 23.14746; lng = 113.34175376; var myLatLng = new google.maps.LatLng(lat, lng); var myOptions = { zoom: 15,
springcloud 系列教程四:服務消費者(Feign)
一、Feign簡介 Feign 的英文表意為 "假裝,偽裝,變形", 是一個http請求呼叫的輕量級框架,可
WebGL簡易教程(四):顏色
目錄 1. 概述 2. 示例:繪製三角形 1) 資料的組織 2) varying變數 3. 結果 4. 理解 1) 圖形裝配和光柵化
Lucene4.10使用教程(六):Lucene的過濾器
package com.johnny.lucene04.advance_search; import java.io.IOException; import org.apache.lucene.index.AtomicReaderContext; import org.apache.lucene.index.
Lucene4.10使用教程(九):Tika
package com.johnny.lucene05.lucene_plugin.tika; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import org.apache.commons.
《C#圖解教程》讀書筆記之四:類和繼承
intern html pan 類中訪問 ted obj 小寫 his new 本篇已收錄至《C#圖解教程》讀書筆記目錄貼,點擊訪問該目錄可獲取更多內容。 一、萬物之宗:Object (1)除了特殊的Object類,其他所有類都是派生類,即使他們沒有顯示基類定義。
Spring 基礎教程之四:JavaBean基本配置詳解
一:xml 裝配JavaBean屬性含義: 1.id:指定該Bean 的唯一標識。 2.class:指定該Bean 的全限定名。 3.name:為該Bean 指定一到多個別名。多個別名可以用“,”和“;”分割。