假如你像用lucene来作分组,比如按类别分组,这种功能,好了你压力大了,lucene本身是不支持分组的。

当你想要这个功能的时候,就可能会用到基于lucene的搜索引擎solr。

不过也可以通过编码通过FieldCache和单字段,对索引进行分组,比如:想构造类别树。大类里面还有小类那种。

这个功能实现起来可能会比较麻烦,主要是lucene提供的支持也不多,参考资料也不多。

(以下代码都是我在做测试的时候做的,可以稍作修改满足相应需求。)

//用于分组统计的对象GroupCollector

import java.io.IOException;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Collector;
import org.apache.lucene.search.Scorer;

public class GroupCollector extends Collector {

private GroupField gf = new GroupField();// 保存分组统计结果
    private int docBase;
    // fieldCache
    private String[] fc;

@Override
    public boolean acceptsDocsOutOfOrder() {
        return true;
    }

@Override
    public void collect(int doc) throws IOException {
        // 因为doc是每个segment的文档编号,需要加上docBase才是总的文档编号
        final int docId = doc + this.docBase;
        // 添加的GroupField中,由GroupField负责统计每个不同值的数目
        this.gf.addValue(this.fc[docId]);

}

@Override
    public void setNextReader(IndexReader arg0, int arg1) throws IOException {
        this.docBase = this.docBase;

}

@Override
    public void setScorer(Scorer arg0) throws IOException {

}

public GroupField getGf() {
        return this.gf;
    }

public void setGf(GroupField gf) {
        this.gf = gf;
    }

public int getDocBase() {
        return this.docBase;
    }

public void setDocBase(int docBase) {
        this.docBase = docBase;
    }

public String[] getFc() {
        return this.fc;
    }

public void setFc(String[] fc) {
        this.fc = fc;
    }

}

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用于保存分组统计后每个字段的分组结果
 */
public class GroupField {

/**
     * 字段名
     */
    private String name;
    /**
     * 商品类型的对象列表
     */
    private List<SimpleCategory> values = new ArrayList<SimpleCategory>();
    /**
     * 保存字段值和文档个数的对应关系
     */
    private Map<String, Integer> countMap = new HashMap<String, Integer>();

public Map<String, Integer> getCountMap() {
        return this.countMap;
    }

public void setCountMap(Map<String, Integer> countMap) {
        this.countMap = countMap;
    }

public String getName() {
        return this.name;
    }

public void setName(String name) {
        this.name = name;
    }

public List<SimpleCategory> getValues() {
        return this.values;
    }

public void setValues(List<SimpleCategory> values) {
        this.values = values;
    }

/**
     * 用于商品对象list的构造
     * 
     * @param value
     */
    public void addValue(String value) {
        if ((value == null) || "".equals(value)) return;
        // 对于多值的字段,支持按空格拆分
        final String[] temp = value.split(",");

if (this.countMap.get(temp[1]) == null) {
            this.countMap.put(temp[1], 1);
            // 构造商品类型临时对象
            final SimpleCategory simpleCategory = new SimpleCategory();

simpleCategory.setCategoryId(Integer.parseInt(temp[0]));
            simpleCategory.setCategoryName(temp[1]);
            simpleCategory.setParentId(Integer.parseInt(temp[2]));
            simpleCategory.setSortIndex(temp[3]);
            simpleCategory.setParentCategoryName(temp[4]);
            // simpleCategory.setAdImag(temp[5]);
            // simpleCategory.setParentAdImage(temp[6]);
            this.values.add(simpleCategory);
        }
        else {
            this.countMap.put(temp[1], this.countMap.get(temp[1]) + 1);
        }
        // for( String str : temp ){
        // if(countMap.get(str)==null){
        // countMap.put(str,1);
        // values.add(str);
        // }
        // else{
        // countMap.put(str, countMap.get(str)+1);
        // }
        // }
    }
    // class ValueComparator implements Comparator<String>{
    //
    // // public int compare(String value0, String value1) {
    // // if(countMap.get(value0)>countMap.get(value1)){
    // // return -1;
    // // }
    // // else if(countMap.get(value0)<countMap.get(value1)){
    // // return 1;
    // // }
    // // return 0;
    // // }
    // }
}

自己构建想返回的对象

/**
 * 用于将lucene索引中的商品类型CategoryIndex字段,转换成商品类型的一个对象。
 * 
 * @author xiaozd
 * 
 */
public class SimpleCategory extends BaseModel {

private static final long serialVersionUID = -2345212345526771266L;
    private int parentId;
    private int categoryId;
    private String categoryName;
    private String sortIndex;
    private int goodsCount;
    private String parentCategoryName;

public int getParentId() {
        return this.parentId;
    }

public void setParentId(int parentId) {
        this.parentId = parentId;
    }

public int getCategoryId() {
        return this.categoryId;
    }

public void setCategoryId(int categoryId) {
        this.categoryId = categoryId;
    }

public String getCategoryName() {
        return this.categoryName;
    }

public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

public String getSortIndex() {
        return this.sortIndex;
    }

public void setSortIndex(String sortIndex) {
        this.sortIndex = sortIndex;
    }

public static long getSerialversionuid() {
        return SimpleCategory.serialVersionUID;
    }

public int getGoodsCount() {
        return this.goodsCount;
    }

public void setGoodsCount(int goodsCount) {
        this.goodsCount = goodsCount;
    }

public String getParentCategoryName() {
        return this.parentCategoryName;
    }

public void setParentCategoryName(String parentCategoryName) {
        this.parentCategoryName = parentCategoryName;
    }

}

/**
     * 查询商品的所有类型,方式:通过索引分组查询所有类型。
     *     @return    Map<String, String> 第一个参数表示商品类型id,第二个String表示商品类型名称
     */
    public List<SimpleCategory> getGoodsCategory() {
        
        List<SimpleCategory> values=new ArrayList<SimpleCategory>();
        try {
            
            IndexReader reader = IndexReader.open(FSDirectory.open(new File(luceneSearchPath)), true); // only searching, so read-only=true

//读取"modified"字段值,放到fieldCache中
            final String[] fc=FieldCache.DEFAULT.getStrings(reader, "categoryIndex");
            IndexSearcher searcher = new IndexSearcher(reader);
            //GroupCollector是自定义文档收集器,用于实现分组统计
            GroupCollector myCollector=new GroupCollector();
            myCollector.setFc(fc);
            searcher.search(new MatchAllDocsQuery(), myCollector);
            //GroupField用来保存分组统计的结果
            GroupField gf=myCollector.getGf();
            values=gf.getValues();
            for (SimpleCategory value : values) {
                System.out.println("商品类型名称:  "+value +"  数量:"+gf.getCountMap().get(value.getCategoryName())+"   商品父类型名称: "+value.getParentCategoryName());
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return values;
    }

http://blog.csdn.net/xiaozhengdong/article/details/7035607

用Lucene实现分组,facet功能,FieldCache的更多相关文章

  1. lucene搜索之facet查询原理和facet查询实例——TODO

    转自:http://www.lai18.com/content/7084969.html Facet说明 我们在浏览网站的时候,经常会遇到按某一类条件查询的情况,这种情况尤以电商网站最多,以天猫商城为 ...

  2. MYSQL-实现ORACLE- row_number() over(partition by ) 分组排序功能

    MYSQL-实现ORACLE- row_number() over(partition by ) 分组排序功能 由于MYSQL没有提供类似ORACLE中OVER()这样丰富的分析函数. 所以在MYSQ ...

  3. SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表

    SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表 SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表 2013-10-09 23:09 by BI Wor ...

  4. Lucene最重要的功能是对一段话的分析

    Lucene最重要的功能是对一段话的分析

  5. MYSQL-实现分组排序 对比 ORACLE 和SQLserver用 row_number() over(partition by ) 分组排序功能

    以下是个人笔记: 本文是为了理解 row_number() over(partition by )  和实现各种数据库的分组排序功能 select ROW_NUMBER()over( partitio ...

  6. 相似group by的分组计数功能

    之前同事发过一个语句,实现的功能比較简单,相似group by的分组计数功能,由于where条件有like,又无法用group by来实现. SELECT a.N0,b.N1,c.N2,d.N3,e. ...

  7. 使用Lucene.NET实现数据检索功能

    引言     在软件系统中查询数据是再平常不过的事情了,那当数据量非常大,数据存储的媒介不是数据库,或者检索方式要求更为灵活的时候,我们该如何实现数据的检索呢?为数据建立索引吧,利用索引技术可以更灵活 ...

  8. FastScroll(2)不分组的listview 打开fastscroll的分组提示功能

    本文只让fastscroll具有提示分组功能,但listview并不显示分组,如果想让分组的listview显示fastscroll,看下篇. 1,在listview中打开fastscroll 2,自 ...

  9. BuguMongo是一个MongoDB Java开发框架,集成了DAO、Query、Lucene、GridFS等功能

    http://code.google.com/p/bugumongo/ 简介 BuguMongo是一个MongoDB Java开发框架,它的主要功能包括: 基于注解的对象-文档映射(Object-Do ...

随机推荐

  1. python-条件和循环

    条件 Demo1: if i < 10: print('i<10') elif i == 0: print('i=0 ') else: print('...') Demo1说明了以下几点: ...

  2. mysql与redis的区别与联系

    1.mysql是关系型数据库,主要用于存放持久化数据,将数据存储在硬盘中,读取速度较慢. redis是NOSQL,即非关系型数据库,也是缓存数据库,即将数据存储在缓存中,缓存的读取速度快,能够大大的提 ...

  3. 注册google账号 解决国内手机注册失败的问题

    1. PC端下载夜神安卓模拟器.安装,启动. 2. 在模拟器里的市场应用里下载qq邮箱. 3. 启动邮箱,选择gmail,注册.后续一切顺利. 这是迄今为止,唯一注册顺利的方法.其他方法,手机验证一关 ...

  4. Python issubclass() 函数

    Python issubclass() 函数  Python 内置函数 描述 issubclass() 方法用于判断参数 class 是否是类型参数 classinfo 的子类. 语法 以下是 iss ...

  5. iOS 代码调试

    僵尸对象导致crash(Thread 1:EXC_BAD_ACCESS(code=EXC_I386_GPFLT)),需要给位release模式,debug模式不打印内存地址 https://blog. ...

  6. OC线程操作-GCD介绍

    1. GCD介绍 1.11.2 1.3 异步具备开启能力但是不是 一定可以开启 1.4 1.5 67. 8.

  7. Linux 下 FastDFS v5.08 分布式文件系统的安装

    一.系统安装目录 源代码包目录 /data/wwwroot libevent安装目录 /usr/local/libevent FastDFS安装目录 /data/fastdfs nginx安装目录 / ...

  8. PHP下ajax跨子域的解决方案之document.domain+iframe

    对于主域相同,子域不同,我们可以设置相同的document.domain来欺骗浏览器,达到跨子域的效果.   例如:我们有两个域名:www.a.com 和 img.a.com 在www.a.com下有 ...

  9. linux下安装php php-fpm(转载)

    centos安装php php-fpm 1.下载php源码包http://www.php.net/downloads.php2 .安装phptar -xvf php-5.5.13.tar.bz2cd ...

  10. SQL思维导图