package src;
import java.io.StringReader;
import java.util.Date;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.SimpleAnalyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.cjk.CJKAnalyzer;
import org.apache.lucene.analysis.cn.ChineseAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.DateField;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.QueryFilter;
import org.apache.lucene.search.RangeQuery;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
public class LuceneSearch {
public static void main(String[] args) throws Exception{
LuceneSearch test = new LuceneSearch();
//
Hits h = null;
h = test.search("顯示 ");
test.printResult(h);
h = test.search("jy");
h = test.search("djy");
h = test.search("料不");
h = test.search("人");
}
public LuceneSearch(){
try{
searcher = new IndexSearcher(IndexReader.open("E://lucene//test4//index"));
}catch(Exception e){
e.printStackTrace();
}
//聲明一個IndexSearcher對象
private IndexSearcher searcher = null;
//聲明一個Query對象
private Query query = null;
ChineseAnalyzer analyzer = new ChineseAnalyzer();
Highlighter highlighter = null;
public final Hits search(String keyword){
System.out.println("正在檢索關鍵字:"+keyword);
Date start = new Date();
/***** 一個關鍵字,對一個字段進行查詢 *****/
QueryParser qp = new QueryParser("content",analyzer);
query = qp.parse(keyword);
// Hits hits = searcher.search(query);
/***** 模糊查詢 *****/
// Term term = new Term("content",keyword);
// FuzzyQuery fq = new FuzzyQuery(term);
// Hits hits = searcher.search(fq);
/***** 一個關鍵字,在兩個字段中查詢 *****/
/*
* 1.BooleanClause.Occur[]的三種類型:
* MUST : + and
* MUST_NOT : - not
* SHOULD : or
* 2.下面查詢的意思是:content中必須包含該關鍵字,而title有沒有都無所謂
* 3.下面的這個查詢中,Occur[]的長度必須和Fields[]的長度一緻。每個限制條件對應一個字段
*/
// BooleanClause.Occur[] flags = new BooleanClause.Occur[]{BooleanClause.Occur.SHOULD,BooleanClause.Occur.MUST};
// query=MultiFieldQueryParser.parse(keyword,new String[]{"title","content"},flags,analyzer);
/***** 兩個(多個)關鍵字對兩個(多個)字段進行查詢,預設比對規則 *****/
* 1.關鍵字的個數必須和字段的個數相等
* 2.由于沒有指定比對規定,預設為"SHOULD"
* 是以,下面查詢的意思是:"title"中含有keyword1 或 "content"含有keyword2.
* 在此例中,把keyword1和keyword2相同
// query=MultiFieldQueryParser.parse(new String[]{keyword,keyword},new String[]{"title","content"},analyzer);
/***** 兩個(多個)關鍵字對兩個(多個)字段進行查詢,手工指定比對規則 *****/
* 1.必須 關鍵字的個數 == 字段名的個數 == 比對規則的個數
* 2.下面查詢的意思是:"title"必須不含有keyword1,并且"content"中必須含有keyword2
// BooleanClause.Occur[] flags = new BooleanClause.Occur[]{BooleanClause.Occur.MUST_NOT,BooleanClause.Occur.MUST};
// query=MultiFieldQueryParser.parse(new String[]{keyword,keyword},new String[]{"title","content"},flags,analyzer);
/***** 對日期型字段進行查詢 *****/
/***** 對數字範圍進行查詢 *****/
* 1.兩個條件必須是同一個字段
* 2.前面一個條件必須比後面一個條件小,否則找不到資料
* 3.new RangeQuery中的第三個參數,表示是否包含"="
* true: >= 或 <=
* false: > 或 <
* 4.找出 55>=id>=53 or 60>=id>=57:
// Term lowerTerm1 = new Term("id","53");
// Term upperTerm1 = new Term("id","55");
// RangeQuery rq1 = new RangeQuery(lowerTerm1,upperTerm1,true);
//
// Term lowerTerm2 = new Term("id","57");
// Term upperTerm2 = new Term("id","60");
// RangeQuery rq2 = new RangeQuery(lowerTerm2,upperTerm2,true);
// BooleanQuery bq = new BooleanQuery();
// bq.add(rq1,BooleanClause.Occur.SHOULD);
// bq.add(rq2,BooleanClause.Occur.SHOULD);
//手工拼範圍
// query = QueryParser.Parse("{200004 TO 200206}", "pubmonth", new SimpleAnalyzer());
// Lucene用[] 和{}分别表示包含和不包含.
//String temp = "startDate:["+nextWeek[0]+" TO "+nextWeek[1]+"] ";
// temp = temp + " OR endDate:["+nextWeek[0]+" TO "+nextWeek[1]+"]";
// Query query1 = qp.parse(temp);
// Hits hits = searcher.search(bq);
/***** 排序 *****/
* 1.被排序的字段必須被索引過(Indexecd),在索引時不能 用 Field.Index.TOKENIZED
* (用UN_TOKENIZED可以正常實作.用NO時查詢正常,但排序不能正常設定升降序)
* 2.SortField類型
* SCORE、DOC、AUTO、STRING、INT、FLOAT、CUSTOM
* 此類型主要是根據字段的類型選擇
* 3.SortField的第三個參數代表是否是降序
* true:降序 false:升序
// Sort sort = new Sort(new SortField[]{new SortField("id", SortField.INT, true)});
// Hits hits = searcher.search(query,sort);
* 按日期排序
// Sort sort = new Sort(new SortField[]{new SortField("createTime", SortField.INT, false)});
/***** 過濾器 ******/
// QueryParser qp1 = new QueryParser("content",analyzer);
// Query fquery = qp1.parse("我");
//
// BooleanQuery bqf = new BooleanQuery();
// bqf.add(fquery,BooleanClause.Occur.SHOULD);
// QueryFilter qf = new QueryFilter(bqf);
Hits hits = searcher.search(query);
Date end = new Date();
System.out.println("檢索完成,用時"+(end.getTime()-start.getTime())+"毫秒");
return hits;
return null;
public void printResult(Hits h){
if(h.length() == 0){
System.out.println("對不起,沒有找到您要的結果.");
}else{
for(int i = 0; i < h.length(); i++){
try{
Document doc = h.doc(i);
System.out.println("結果"+(i+1)+":"+doc.get("id")+" createTime:"+doc.get("createTime")+" title:"+doc.get("title")+" content:"+doc.get("content"));
//System.out.println(doc.get("path"));
}catch(Exception e){
e.printStackTrace();
}
}
System.out.println("--------------------------------------");
}
需要說明的一點是,本例用到了Chinese分析器,需要導入相應的包!