天天看點

lucene多種搜尋方式詳解例子

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分析器,需要導入相應的包!

繼續閱讀