【lucene】進階搜尋篇

來源:互聯網
上載者:User

一,概念

1、 Lucene相關排序流程

       找到關鍵詞匹配的文檔集合---->文檔集合每個文檔計算檢索相似性----->對文檔集合進行排序

2、 Lucene相關類

① Query類:一個抽象類別, Lucene檢索結果最終評分的總控制中心。其它評分有關的類和對象都是由 Query類來管理和生產。

② Weight類介面:定義 Query權重計算的一個實現介面,可以被重用。 Weight類可以用來產生 Scorer類,也可以解析評分的詳細資料,另外還定義了擷取 Query權值的方法。

③ Scorer類: Lucene評分機制的核心類。類的定義是抽象類別,提供的一些抽象基本的計分功能方法提供所有的評分類實現,同時還定義了評分的詳細解析方法, Scorer類內部有一個 Similarity對象,用來指明計算公式。

④ Scorer類: Lucene相似性計算的核心抽象類別。 Similarity類主要處理評分計算,系統預設使用類 DefaultSimilarity類對象

3、 排序控制

使用 Sort對象定製排序,通過改變文檔 Boost值來改變排序結果以及使用自訂的 Similarity方法更改排序

4、 文檔 Boost加權排序

① Boost是指索引建立過程中,給整篇文檔或者文檔的某一特定域設定的權值因子,在檢索時,優先返回分數高的。

               Document和 Field兩重 Boosting參數。通過 Document對象的 setBoost()方法和 Field對象的 setBoost()方法。不同在於前者對文檔中每一個域都修改了參數,而後者只針對指定域進行修改。

               文檔加權 =Document-boosting*Field-boosting,預設情況下為 1,一般不做修改。

② Sort對象檢索排序

               Sort使用時通過執行個體化對象作為參數,通過 Searcher類的 search介面來實現。 Sort支援的排序功能以文檔當中的域為單位,通過這種方法,可以實現一個或者多個不同域的多形式的值排序。

              實際使用排序對象 Sort進行排序。主要有兩種模式,一種是以字串表示文檔域的名稱作為參數指定域排序,一種是直接以排序域的封裝域的封裝類作為參數進行排序。

              Sort對象使用比較簡單,只需要在對文檔索引進行檢索時,在檢索器的 Search方法中帶 Sort對象作為參數即可。

1) Sort物件相依性排序

              按照相關性排序時最基本的結果排序方法,使用 Sort對象無參數建構函式完成的排序效果相當於 Lucene預設的按相關性降序排序。

2) Sort對象文檔編號排序

             某些應用場合需要對所有符合匹配度的結果,按照文檔內部編號排序輸出。使用 Sort對象的靜態執行個體 Sort.INDEXORDER來實現

3) Sort對象獨立域排序

             在檢索過程中,把檢索結果按照某一個特定域排序,非常重要。在使用搜尋引擎過程中,有時會選擇使用時間排序,而在搜尋引擎庫中,檢索詞完全是另外一個域的內容,與時間沒有任何關係。這種應用中,檢索關鍵詞的匹配仍然是首要因素,匹配太低或者不匹配的文檔直接不必處理,而匹配的文檔則需進一步排序輸出。

指定的排序域並沒有進行特別限制,可以是檢索詞的關聯域,也可以是文檔中的任意其它域。

4) Sort對象聯合域排序

               多個文檔域聯合排序時,需要注意文檔域的添加次序。排序的結果先按照第一個域排序,然後第二個域作為次要關鍵字排序。開發時,需要根據自己的需要選擇合適的次序。

5) Sort對象逆向排序

               Sort(field,true)或者 Sort(field,false)實現升降序排序。

二,例子

/* * To change this template, choose Tools | Templates * and open the template in the editor. */package sorttest;import java.io.File; import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.Term;import org.apache.lucene.index.IndexWriter.MaxFieldLength;import org.apache.lucene.search.IndexSearcher;import org.apache.lucene.search.ScoreDoc;import org.apache.lucene.search.Sort;import org.apache.lucene.search.TermQuery;import org.apache.lucene.store.Directory;import org.apache.lucene.store.FSDirectory;import org.apache.lucene.util.Version; public class SortTest {public static void makeItem(IndexWriter writer, String bookNumber,    String bookName, String publishDate) throws Exception {   writer.setUseCompoundFile(false);   Document doc = new Document();   Field f1 = new Field("bookNumber", bookNumber, Field.Store.YES,     Field.Index.NOT_ANALYZED);   Field f2 = new Field("bookName", bookName, Field.Store.YES,     Field.Index.ANALYZED);   Field f3 = new Field("publishDate", publishDate, Field.Store.YES,     Field.Index.NOT_ANALYZED);   doc.add(f1);   doc.add(f2);   doc.add(f3);   writer.addDocument(doc);} public static void main(String[] args) {   String Index_Store_Path = "D:\\luceneIndex";   File file = new File(Index_Store_Path);    try {    Directory Index = FSDirectory.open(file);    IndexWriter writer = new IndexWriter(Index, new StandardAnalyzer(Version.LUCENE_CURRENT), true,MaxFieldLength.LIMITED);    writer.setUseCompoundFile(false);       Document doc1 = new Document();    Field f11 = new Field("bookNumber", "0000001", Field.Store.YES, Field.Index.NOT_ANALYZED);    Field f12 = new Field("bookName", " 鋼鐵是怎樣煉成的 ", Field.Store.YES, Field.Index.ANALYZED);    Field f13 = new Field("publishDate", "1970-01-01", Field.Store.YES, Field.Index.NOT_ANALYZED);    doc1.add(f11);    doc1.add(f12);    doc1.add(f13);       Document doc2 = new Document();    Field f21 = new Field("bookNumber", "0000002", Field.Store.YES, Field.Index.NOT_ANALYZED);    Field f22 = new Field("bookName", " 鋼鐵戰士 ", Field.Store.YES, Field.Index.ANALYZED);    Field f23 = new Field("publishDate", "1970-01-01", Field.Store.YES, Field.Index.NOT_ANALYZED);    doc2.add(f21);    doc2.add(f22);    doc2.add(f23);       Document doc3 = new Document();    Field f31 = new Field("bookNumber", "0000003", Field.Store.YES, Field.Index.NOT_ANALYZED);    Field f32 = new Field("bookName", " 籬笆女人和狗 ", Field.Store.YES, Field.Index.ANALYZED);    Field f33 = new Field("publishDate", "1970-01-01", Field.Store.YES, Field.Index.NOT_ANALYZED);    doc3.add(f31);    doc3.add(f32);    doc3.add(f33);       Document doc4 = new Document();    Field f41 = new Field("bookNumber", "0000004", Field.Store.YES, Field.Index.NOT_ANALYZED);    Field f42 = new Field("bookName", " 女人是水做的 ", Field.Store.YES, Field.Index.ANALYZED);    Field f43 = new Field("publishDate", "1970-01-01", Field.Store.YES, Field.Index.NOT_ANALYZED);    doc4.add(f41);    doc4.add(f42);    doc4.add(f43);       Document doc5 = new Document();    Field f51 = new Field("bookNumber", "0000005", Field.Store.YES, Field.Index.NOT_ANALYZED);    Field f52 = new Field("bookName", " 英雄兒女 ", Field.Store.YES, Field.Index.ANALYZED);    Field f53 = new Field("publishDate", "1970-01-01", Field.Store.YES, Field.Index.NOT_ANALYZED);    doc5.add(f51);    doc5.add(f52);    doc5.add(f53);       Document doc6 = new Document();    Field f61 = new Field("bookNumber", "0000006", Field.Store.YES, Field.Index.NOT_ANALYZED);    Field f62 = new Field("bookName", " 白毛女 ", Field.Store.YES, Field.Index.ANALYZED);    Field f63 = new Field("publishDate", "1970-01-01", Field.Store.YES, Field.Index.NOT_ANALYZED);    doc6.add(f61);    doc6.add(f62);    doc6.add(f63);       Document doc7 = new Document();    Field f71 = new Field("bookNumber", "0000007", Field.Store.YES, Field.Index.NOT_ANALYZED);    Field f72 = new Field("bookName", " 我的兄弟和女兒 ", Field.Store.YES, Field.Index.ANALYZED);    Field f73 = new Field("publishDate", "1970-01-01", Field.Store.YES, Field.Index.NOT_ANALYZED);    doc7.add(f71);    doc7.add(f72);    doc7.add(f73);       writer.addDocument(doc1);    writer.addDocument(doc2);    writer.addDocument(doc3);    writer.addDocument(doc4);    writer.addDocument(doc5);    writer.addDocument(doc6);    writer.addDocument(doc7);    writer.optimize();    writer.close();        IndexSearcher searcher = new IndexSearcher(Index);    TermQuery q = new TermQuery(new Term("bookName", "女"));       //ScoreDoc[] hits = searcher.search(q, null, 1000, Sort.RELEVANCE).scoreDocs;    //ScoreDoc[] hits = searcher.search(q, null, 1000, Sort.INDEXORDER).scoreDocs;    ScoreDoc[] hits = searcher.search(q, null, 1000).scoreDocs;    for (int i = 0; i < hits.length; i++) {     Document hitDoc = searcher.doc(hits[i].doc);     System.out.print("書名 :");     System.out.println(hitDoc.get("bookName"));     System.out.print("得分 :");     System.out.println(hits[i].score);     System.out.print("內部 ID :");     System.out.println(hits[i].doc);     System.out.print("書號 :");     System.out.println(hitDoc.get("bookNumber"));     System.out.print("發行日期 :");     System.out.println(hitDoc.get("publishDate"));    }   } catch (Exception e) {    e.printStackTrace();   }}}

在代碼中

    //ScoreDoc[] hits = searcher.search(q, null, 1000, Sort.RELEVANCE).scoreDocs;
    //ScoreDoc[] hits = searcher.search(q, null, 1000, Sort.INDEXORDER).scoreDocs;
    ScoreDoc[] hits = searcher.search(q, null, 1000).scoreDocs;

根據不同的Sort 屬性就會得到不同的結果。自己嘗試一下吧

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.