Lucene检索笔记

把Document映射为Object类

public interface Doc2ObjectMapper {
    /**
     * 将多个Document映射成一个对象
     * @param documents
     * @return
     */
    Object mapDocumentsToObject(List<Document> documents);


    /**
     * 将单个Document映射成一个对象
     * @param document
     * @return
     */
    Object mapDocumentToObject(Document document);
}

普通检索

public class SearchHelper {

    private Analyzer analyzer;
    private String indexDirUrl;
    private Directory directory;
    private IndexReader reader;
    private IndexSearcher indexSearcher;


    public SearchHelper(String indexDirUrl,Analyzer analyzer){
        this.indexDirUrl=indexDirUrl;
        this.analyzer=analyzer;
        try {
            init();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public SearchHelper(String indexDirUrl){
        this(indexDirUrl, new SmartChineseAnalyzer());
    }


    private void init() throws IOException {
        directory=FSDirectory.open(Paths.get(indexDirUrl));
        reader= DirectoryReader.open(directory);
        indexSearcher=new IndexSearcher(reader);
    }

    /**
     * 查询并且返回经过映射后的对象List
     * @param query
     * @param offset
     * @param topN
     * @return
     * @throws IOException
     */
    public List<Object> search(Query query,int offset,int topN,Sort sort,Doc2ObjectMapper doc2ObjectMapper) throws IOException {
        TopDocs topDocs=null;
        ScoreDoc after=null;
        if(offset>0){
            TopDocs docsBefore=indexSearcher.search(query,offset,sort);
            ScoreDoc[] scoreDocs=docsBefore.scoreDocs;
            if(scoreDocs.length>0)
                after=scoreDocs[scoreDocs.length-1];
        }
        topDocs=indexSearcher.searchAfter(after,query,topN,sort);
        return creatObjectList(topDocs.scoreDocs,doc2ObjectMapper);
    }

    /**
     * 没有Sort的search
     * @param query
     * @param offset
     * @param topN
     * @return
     * @throws IOException
     */
    public List<Object> search(Query query,int offset,int topN,Doc2ObjectMapper doc2ObjectMapper) throws IOException {
        TopDocs topDocs=null;
        ScoreDoc after=null;
        if(offset>0){
            TopDocs docsBefore=indexSearcher.search(query,offset);
            ScoreDoc[] scoreDocs=docsBefore.scoreDocs;
            if(scoreDocs.length>0)
                after=scoreDocs[scoreDocs.length-1];
        }
        topDocs=indexSearcher.searchAfter(after,query,topN);

        return creatObjectList(topDocs.scoreDocs,doc2ObjectMapper);
    }



    /**
     * 获取查询到的总数量
     * @param query
     * @return
     * @throws IOException
     */
    public int getSum(Query query) throws IOException {
        return indexSearcher.search(query,1).totalHits;
    }

    private List<Object> creatObjectList(ScoreDoc[] scoreDocs,Doc2ObjectMapper doc2ObjectMapper) throws IOException {
        List<Object> result=new LinkedList<Object>();
        for(ScoreDoc scoreDoc:scoreDocs){
            result.add(doc2ObjectMapper.mapDocumentToObject(indexSearcher.doc(scoreDoc.doc)));
        }
        return result;
    }

}

基于Group by的检索

/**
 * 使用Group by进行搜索
 * Created by yuan on 1/8/17.
 */
public class GroupSearcherHelper {

    private Analyzer analyzer;
    private String indexDirUrl;
    private Directory directory;
    private IndexReader reader;
    private IndexSearcher indexSearcher;
    private double maxCacheRAMMB;
    private boolean isCacheScores=true;
    private boolean ifFillFields=true;

    public static final double DEFAULT_MAX_CACHE_RAM_MB=4.0;

    public GroupSearcherHelper(String indexDirUrl,Analyzer analyzer,double maxCacheRAMMB){
        this.indexDirUrl=indexDirUrl;
        this.analyzer=analyzer;
        this.maxCacheRAMMB=maxCacheRAMMB;
        try {
            init();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public GroupSearcherHelper(String indexDirUrl,Analyzer analyzer){
        this(indexDirUrl,analyzer,DEFAULT_MAX_CACHE_RAM_MB);
    }

    public GroupSearcherHelper(String indexDirUrl){
        this(indexDirUrl,new SmartChineseAnalyzer());
    }



    private void init() throws IOException {
        directory= FSDirectory.open(Paths.get(indexDirUrl));
        reader= DirectoryReader.open(directory);
        indexSearcher=new IndexSearcher(reader);
    }


    /**
     * 搜索返回文档分组
     * @param query
     * @param groupFieldName
     * @param groupSort
     * @param withinGroupSort
     * @param groupOffset
     * @param topNGroups
     * @return
     * @throws IOException
     */
    public List<List<Document>> searchDocument(Query query, String groupFieldName, Sort groupSort, Sort withinGroupSort, int groupOffset, int topNGroups) throws IOException {
        List<List<Document>> result=new LinkedList<List<Document>>();
        TopGroups<BytesRef> topGroupsResult=searchHelp(query,groupFieldName,groupSort,withinGroupSort,groupOffset,topNGroups);
        if(topGroupsResult==null)
            return result;
        GroupDocs<BytesRef>[] groupDocses=topGroupsResult.groups;
        for(GroupDocs<BytesRef> groupDocs:groupDocses){
            List<Document> subList=new LinkedList<Document>();
            for(ScoreDoc scoreDoc:groupDocs.scoreDocs){
                Document document=indexSearcher.doc(scoreDoc.doc);
                subList.add(document);
            }
            result.add(subList);
        }

        return result;
    }

    /**
     * 使用默认Sort的searchDocument
     * @param query
     * @param groupFieldName
     * @param groupOffset
     * @param topNGroups
     * @return
     * @throws IOException
     */
    public List<List<Document>> searchDocument(Query query, String groupFieldName, int groupOffset, int topNGroups) throws IOException {
        return searchDocument(query,groupFieldName,Sort.INDEXORDER,Sort.INDEXORDER,groupOffset,topNGroups);
    }

    /**
     * 分组搜索并且将每一组Document映射成一个对象并且返回所有对象组成的List
     * @param query
     * @param groupFieldName
     * @param groupSort
     * @param withinGroupSort
     * @param groupOffset
     * @param topNGroups
     * @param mapper
     * @return
     * @throws IOException
     */
    public List<Object> search(Query query, String groupFieldName, Sort groupSort, Sort withinGroupSort, int groupOffset, int topNGroups, Doc2ObjectMapper mapper) throws IOException {
        List<Object> result=new LinkedList<Object>();
        List<List<Document>> documentsList=searchDocument(query,groupFieldName,groupSort,withinGroupSort,groupOffset,topNGroups);
        if(documentsList.size()==0)
            return result;
        Object o=null;
        for(List<Document> documents:documentsList){
            o=mapper.mapDocumentsToObject(documents);
            result.add(o);
        }
        return result;
    }

    /**
     * 使用默认Sort的search
     * @param query
     * @param groupFieldName
     * @param groupOffset
     * @param topNGroups
     * @param mapper
     * @return
     * @throws IOException
     */
    public List<Object> search(Query query, String groupFieldName,  int groupOffset, int topNGroups, Doc2ObjectMapper mapper) throws IOException {
        return search(query,groupFieldName,Sort.INDEXORDER,Sort.INDEXORDER,groupOffset,topNGroups,mapper);
    }



    TopGroups<BytesRef> searchHelp(Query query, String groupFieldName, Sort groupSort, Sort withinGroupSort, int groupOffset, int topNGroups) throws IOException {
        TermFirstPassGroupingCollector c1=new TermFirstPassGroupingCollector(groupFieldName,groupSort,groupOffset+topNGroups);
        /**
         * 将TermFirstPassGroupingCollector包装成CachingCollector,为第一次查询加缓存,避免重复评分
         *  CachingCollector就是用来为结果收集器添加缓存功能的
         */
        CachingCollector cachingCollector=CachingCollector.create(c1,isCacheScores,maxCacheRAMMB);
        //开始第一次分组统计
        indexSearcher.search(query,cachingCollector);

        /**第一次查询返回的结果集TopGroups中只有分组域值以及每组总的评分,至于每个分组里有几条,分别哪些索引文档,则需要进行第二次查询获取*/
        Collection<SearchGroup<BytesRef>> topGroups=c1.getTopGroups(groupOffset,ifFillFields);
        if(topGroups==null){
            return null;
        }

        Collector secondPassCollector=null;
        // 是否获取每个分组内部每个索引的评分
        boolean ifGetScores=true;
        // 是否计算最大评分
        boolean ifGetMaxScores=true;
        int maxDocsPerGroup=10;
        // 如果需要对Lucene的score进行修正,则需要重载TermSecondPassGroupingCollector
        TermSecondPassGroupingCollector c2=new TermSecondPassGroupingCollector(groupFieldName,topGroups,
                groupSort,withinGroupSort,
                maxDocsPerGroup,ifGetScores,ifGetMaxScores,ifFillFields);

        secondPassCollector=c2;

        /**如果第一次查询已经加了缓存,则直接从缓存中取*/
        if(cachingCollector.isCached()){
            //第二次查询直接从缓存中取
            cachingCollector.replay(secondPassCollector);
        }else{
            // 开始第二次分组查询
            indexSearcher.search(query,secondPassCollector);
        }


        TopGroups<BytesRef> topGroupsResult=c2.getTopGroups(0);

        return topGroupsResult;
    }

    /**
     * 查询符合条件的分组总数量
     * @param query
     * @param groupFieldName
     * @return
     * @throws Exception
     */
    public int getGroupSum(Query query,String groupFieldName) throws Exception{
        TermFirstPassGroupingCollector c1=new TermFirstPassGroupingCollector(groupFieldName,Sort.INDEXORDER,1);
        TermAllGroupsCollector termAllGroupsCollector=new TermAllGroupsCollector(groupFieldName);
        Collector collector=  MultiCollector.wrap(c1,termAllGroupsCollector);
        indexSearcher.search(query,collector);

        return termAllGroupsCollector.getGroupCount();
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值