欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Java的Lucene搜索工具對檢索結(jié)果進(jìn)行分組和分頁

 更新時間:2016年03月06日 08:52:56   作者:小檀  
這篇文章主要介紹了使用Java的搜索工具Lucene對檢索結(jié)果進(jìn)行分組和分頁的方法,Luence是Java環(huán)境中的一個全文檢索引擎工具包,需要的朋友可以參考下

使用GroupingSearch對搜索結(jié)果進(jìn)行分組
Package org.apache.lucene.search.grouping Description

這個模塊可以對Lucene的搜索結(jié)果進(jìn)行分組,指定的單值域被聚集到一起。比如,根據(jù)”author“域進(jìn)行分組,“author”域值相同的的文檔分成一個組。

進(jìn)行分組的時候需要輸入一些必要的信息:

1、groupField:根據(jù)這個域進(jìn)行分組。比如,如果你使用“author”域進(jìn)行分組,那么每一個組里面的書籍都是同一個作者。沒有這個域的文檔將被分到一個單獨的組里面。

2、groupSort:組排序。

3、topNGroups:保留多少組。比如,10表示只保留前10組。

4、groupOffset:對排在前面的哪些分組組進(jìn)行檢索。比如,3表示返回7個組(假設(shè)opNGroups等于10)。在分頁里面很有用,比如每頁只顯示5個組。

5、withinGroupSort:組內(nèi)文檔排序。注意:這里和groupSort的區(qū)別

6、withingroupOffset:對每一個分組里面的哪些排在前面的文檔進(jìn)行檢索。


使用GroupingSearch 對搜索結(jié)果分組比較簡單

GroupingSearch API文檔介紹:

Convenience class to perform grouping in a non distributed environment.

非分布式環(huán)境下分組

WARNING: This API is experimental and might change in incompatible ways in the next release.

這里使用的是4.3.1版本

一些重要的方法:

  • GroupingSearch:setCaching(int maxDocsToCache, boolean cacheScores) 緩存
  • GroupingSearch:setCachingInMB(double maxCacheRAMMB, boolean cacheScores) 緩存第一次搜索結(jié)果,用于第二次搜索
  • GroupingSearch:setGroupDocsLimit(int groupDocsLimit) 指定每組返回的文檔數(shù),不指定時,默認(rèn)返回一個文檔
  • GroupingSearch:setGroupSort(Sort groupSort) 指定分組排序

示例代碼:

1.先看建索引的代碼

public class IndexHelper {
  private Document document;
  private Directory directory;
  private IndexWriter indexWriter;
 
  public Directory getDirectory(){
    directory=(directory==null)? new RAMDirectory():directory;
    return directory;
  }
 
  private IndexWriterConfig getConfig() {
    return new IndexWriterConfig(Version.LUCENE_43, new IKAnalyzer(true));
  }
 
  private IndexWriter getIndexWriter() {
    try {
      return new IndexWriter(getDirectory(), getConfig());
    } catch (IOException e) {
      e.printStackTrace();
      return null;
    }
  }
 
  public IndexSearcher getIndexSearcher() throws IOException {
    return new IndexSearcher(DirectoryReader.open(getDirectory()));
  }
 
  /**
   * Create index for group test
   * @param author
   * @param content
   */
  public void createIndexForGroup(int id,String author,String content) {
    indexWriter = getIndexWriter();
    document = new Document();
    document.add(new IntField("id",id, Field.Store.YES));
    document.add(new StringField("author", author, Field.Store.YES));
    document.add(new TextField("content", content, Field.Store.YES));
    try {
      indexWriter.addDocument(document);
      indexWriter.commit();
      indexWriter.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

2.分組:

public class GroupTest

public void group(IndexSearcher indexSearcher,String groupField,String content) throws IOException, ParseException {
    GroupingSearch groupingSearch = new GroupingSearch(groupField);
    groupingSearch.setGroupSort(new Sort(SortField.FIELD_SCORE));
    groupingSearch.setFillSortFields(true);
    groupingSearch.setCachingInMB(4.0, true);
    groupingSearch.setAllGroups(true);
    //groupingSearch.setAllGroupHeads(true);
    groupingSearch.setGroupDocsLimit(10);
 
    QueryParser parser = new QueryParser(Version.LUCENE_43, "content", new IKAnalyzer(true));
    Query query = parser.parse(content);
 
    TopGroups<BytesRef> result = groupingSearch.search(indexSearcher, query, 0, 1000);
 
    System.out.println("搜索命中數(shù):" + result.totalHitCount);
    System.out.println("搜索結(jié)果分組數(shù):" + result.groups.length);
 
    Document document;
    for (GroupDocs<BytesRef> groupDocs : result.groups) {
      System.out.println("分組:" + groupDocs.groupValue.utf8ToString());
      System.out.println("組內(nèi)記錄:" + groupDocs.totalHits);
 
      //System.out.println("groupDocs.scoreDocs.length:" + groupDocs.scoreDocs.length);
      for (ScoreDoc scoreDoc : groupDocs.scoreDocs) {
        System.out.println(indexSearcher.doc(scoreDoc.doc));
      }
    }
  }

3.簡單的測試:

public static void main(String[] args) throws IOException, ParseException {
    IndexHelper indexHelper = new IndexHelper();
    indexHelper.createIndexForGroup(1,"紅薯", "開源中國");
    indexHelper.createIndexForGroup(2,"紅薯", "開源社區(qū)");
    indexHelper.createIndexForGroup(3,"紅薯", "代碼設(shè)計");
    indexHelper.createIndexForGroup(4,"紅薯", "設(shè)計");
    indexHelper.createIndexForGroup(5,"覺先", "Lucene開發(fā)");
    indexHelper.createIndexForGroup(6,"覺先", "Lucene實戰(zhàn)");
    indexHelper.createIndexForGroup(7,"覺先", "開源Lucene");
    indexHelper.createIndexForGroup(8,"覺先", "開源solr");
 
    indexHelper.createIndexForGroup(9,"散仙", "散仙開源Lucene");
    indexHelper.createIndexForGroup(10,"散仙", "散仙開源solr");
    indexHelper.createIndexForGroup(11,"散仙", "開源");
    GroupTest groupTest = new GroupTest();
 
    groupTest.group(indexHelper.getIndexSearcher(),"author", "開源");
  }
}

4.測試結(jié)果:

20163684827254.png (1168×355)

兩種分頁方式
Lucene有兩種分頁方式:

1、直接對搜索結(jié)果進(jìn)行分頁,數(shù)據(jù)量比較少的時候可以用這種方式,分頁代碼核心參照:


ScoreDoc[] sd = XXX;
// 查詢起始記錄位置
int begin = pageSize * (currentPage - 1);
// 查詢終止記錄位置
int end = Math.min(begin + pageSize, sd.length);
for (int i = begin; i < end && i <totalHits; i++) {
//對搜索結(jié)果數(shù)據(jù)進(jìn)行處理的代碼
}

2、使用searchAfter(...)

Lucene提供了五個重載方法,可以根據(jù)需要使用

20163684904821.png (1012×281)

ScoreDoc after:為上次搜索結(jié)果ScoreDoc總量減1;

Query query:查詢方式

int n:為每次查詢返回的結(jié)果數(shù),即每頁的結(jié)果總量

一個簡單的使用示例:

//可以使用Map保存必要的搜索結(jié)果
Map<String, Object> resultMap = new HashMap<String, Object>();
ScoreDoc after = null;
Query query = XX
TopDocs td = search.searchAfter(after, query, size);
 
//獲取命中數(shù)
resultMap.put("num", td.totalHits);
 
ScoreDoc[] sd = td.scoreDocs;
for (ScoreDoc scoreDoc : sd) {
//經(jīng)典的搜索結(jié)果處理
}
//搜索結(jié)果ScoreDoc總量減1
after = sd[td.scoreDocs.length - 1]; 
//保存after用于下次搜索,即下一頁開始 
resultMap.put("after", after);
 
return resultMap;

相關(guān)文章

  • String實例化及static final修飾符實現(xiàn)方法解析

    String實例化及static final修飾符實現(xiàn)方法解析

    這篇文章主要介紹了String實例化及static final修飾符實現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • Mybatis自定義類型轉(zhuǎn)換器的使用技巧

    Mybatis自定義類型轉(zhuǎn)換器的使用技巧

    這篇文章主要介紹了Mybatis自定義類型轉(zhuǎn)換器的使用技巧,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • win10安裝JDK14.0.2的詳細(xì)安裝過程

    win10安裝JDK14.0.2的詳細(xì)安裝過程

    這篇文章主要介紹了win10安裝JDK14.0.2的詳細(xì)安裝過程的相關(guān)資料,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • MyBatis中XML映射器的實現(xiàn)

    MyBatis中XML映射器的實現(xiàn)

    MyBatis的真正強(qiáng)大在于它的語句映射,映射器的XML文件就顯得相對簡單,本文主要介紹了MyBatis中XML映射器的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • elasticsearch節(jié)點的transport請求發(fā)送處理分析

    elasticsearch節(jié)點的transport請求發(fā)送處理分析

    這篇文章主要為大家介紹了elasticsearch節(jié)點的transport請求發(fā)送處理分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • Java 如何繞過迭代器遍歷時的數(shù)據(jù)修改異常

    Java 如何繞過迭代器遍歷時的數(shù)據(jù)修改異常

    這篇文章主要介紹了Java 繞過迭代器遍歷時的數(shù)據(jù)修改異常的方法,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-02-02
  • SpringCloud整合Consul的實現(xiàn)

    SpringCloud整合Consul的實現(xiàn)

    這篇文章主要介紹了SpringCloud整合Consul的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Java中加鎖的方式代碼示例

    Java中加鎖的方式代碼示例

    這篇文章主要給大家介紹了關(guān)于Java中加鎖方式的相關(guān)資料,我們平時開發(fā)的過程中難免遇到多線程操作共享資源的時候,這時候一般可以通過加鎖的方式保證操作的安全性,需要的朋友可以參考下
    2023-09-09
  • java.io.UnsupportedEncodingException異常的正確解決方法(親測有效!)

    java.io.UnsupportedEncodingException異常的正確解決方法(親測有效!)

    這篇文章主要給大家介紹了關(guān)于java.io.UnsupportedEncodingException異常的正確解決方法,文中介紹的辦法親測有效,java.io.UnsupportedEncodingException是Java編程語言中的一個異常類,表示指定的字符集不被支持,需要的朋友可以參考下
    2024-02-02
  • Java中&和&&的區(qū)別簡單介紹

    Java中&和&&的區(qū)別簡單介紹

    這篇文章主要介紹了Java中&和&&的區(qū)別,&&邏輯與||邏輯或  它們都是邏輯運算符,& 按位與|按位或它們都是位運算符,更多詳細(xì)內(nèi)容請需要的小伙伴了解下面文章內(nèi)容
    2022-01-01

最新評論