使用lucene進行group操做

近來用lucene進行查詢,須要對結果進行group操做,結果發現核心包裏面沒有提供這個功能。javascript

若是在內存裏面對結果再本身用代碼實現的話效率過低。查詢了一番文檔,發現了lucene-grouping。php

jar包位置:java

<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-grouping</artifactId>
    <version>4.0.0</version>
</dependency>

使用這個包能夠實現對搜索結果進行group操做docker


首先創建索引apache

private Document createDocument(String id, String tag_value,
                                 String score,String city,String time,
                                 String from,String type,String typeId,
                                 String gender,String birthday) {
    Document document = new Document();
    document.add(new TextField("userId", id, Field.Store.YES));
    document.add(new StringField("tagName", tag_value, Field.Store.YES));
    document.add(new StringField("tagScoreValue", score, Field.Store.YES));
    document.add(new StringField("usersCurrentCity", city, Field.Store.YES));
    document.add(new StringField("tagRelatedTime", time, Field.Store.YES));
    document.add(new StringField("dataFrom", from, Field.Store.YES));
    document.add(new StringField("dataType", type, Field.Store.YES));
    document.add(new StringField("dataId", typeId, Field.Store.YES));
    document.add(new StringField("gender", gender, Field.Store.YES));
    document.add(new StringField("birthday", birthday, Field.Store.YES));
    return document;
}


這是個人索引結構,測試用的。測試


下面是個人測試代碼ui

public void testCustomSort() throws Exception {
    List<Document> docs = Arrays.asList(
            createDocument("1", "java", "55", "sz", "2015", "www.yuorfei.com", "blog", "0", "1", "1993"),
            createDocument("1", "php", "56", "sz", "2015", "www.yuorfei.com", "blog", "0", "1", "1993"),
            createDocument("2", "docker", "57", "sz", "2015", "www.yuorfei.com", "blog", "0", "1", "1993"),
            createDocument("2", "php", "55", "sz", "2015", "www.yuorfei.com", "blog", "0", "1", "1993"),
            createDocument("2", "java", "56", "sz", "2015", "www.yuorfei.com", "blog", "0", "1", "1993"),
            createDocument("3", "java", "10", "sz", "2015", "www.yuorfei.com", "blog", "0", "1", "1993"),
            createDocument("4", "javascript", "99", "sz", "2015", "www.yuorfei.com", "blog", "0", "1", "1993"),
            createDocument("4", "java", "99999", "szbjbj44444", "20154444", "www.yuorfei.com", "blog", "0", "1", "1993"));
    LuceneTool.writeDocument(indexDirectoryPath, docs);
 
    String groupField = "userId";
    String tagName="java,php";
 
    GroupingSearch groupingSearch = new GroupingSearch(groupField);
    groupingSearch.setFillSortFields(true);
    groupingSearch.setCachingInMB(4.0, true);
    groupingSearch.setAllGroups(true);
    groupingSearch.setGroupDocsLimit(10);
    TagRadarSearchBuilder tagRadarSearchBuilder = new TagRadarSearchBuilder();
    String[] tagNames = StringUtils.split(tagName, ",");
    tagRadarSearchBuilder.tagName(tagNames).sortedBy(TagRadarSortedCategory.SORTED_BY_TAG_SCORE_VALUE_DESC);
    FSDirectory dir = FSDirectory.open(new File(indexDirectoryPath));
    dir.setReadChunkSize(104857600);//100兆
    IndexReader reader = DirectoryReader.open(dir);
    IndexSearcher indexSearch = new IndexSearcher(reader);
    groupingSearch.setGroupSort(tagRadarSearchBuilder.getSort());
    groupingSearch.setSortWithinGroup(tagRadarSearchBuilder.getSort());
    TopGroups<BytesRef> result = groupingSearch.search(indexSearch, tagRadarSearchBuilder.getQuery(), 0, 1000);
    System.out.println("搜索命中數:" + result.totalHitCount);
    System.out.println("搜索結果分組數:" + result.groups.length);
    System.out.println("\n-------------------------\n");
    for (GroupDocs<BytesRef> groupDocs : result.groups) {
        System.out.println("分組用戶id:" + groupDocs.groupValue.utf8ToString());
        System.out.println("組內記錄數量:" + groupDocs.totalHits);
        for (ScoreDoc scoreDoc : groupDocs.scoreDocs) {
            System.out.println(indexSearch.doc(scoreDoc.doc));
        }
        System.out.println("\n-------------------------\n");
    }
}


最主要的核心的地方是:spa

GroupingSearch groupingSearch = new GroupingSearch(groupField);
groupingSearch.setGroupSort(tagRadarSearchBuilder.getSort());
groupingSearch.setSortWithinGroup(tagRadarSearchBuilder.getSort());
TopGroups<BytesRef> result = groupingSearch.search(indexSearch, tagRadarSearchBuilder.getQuery(), 0, 1000);


設置的排序方法,調用groupSearch的search進行搜索。code

setGroupSort爲組間排序orm

setSortWithinGroup爲組內排序

這樣就能簡單的實現對lucene搜索結果進行group操做,效率很是高。

相關文章
相關標籤/搜索