陋室铭
永远也不要停下学习的脚步(大道至简至易)

posts - 2169,comments - 570,views - 413万

通常,我们的应用系统,如果要做一次全量数据的读取,大多数时候,采用的方式会是使用分页读取的方式,然而
分页读取的方式,在大数据量的情况下,在solr里面表现并不是特别好,因为它随时可能会发生OOM的异常,在solr里面
通过rows和start参数,非常方便分页读取,但是如果你的start=1000000 rows=10,那么solr里面会将前面100万元数据的索引信息读取在内存里面,这样以来,非常耗内存,所以在solr里面,分页并不适合深度分页。

深度分页在solr里面,更推荐使用游标的方式,游标是无状态的,不会维护索引数据在内存里面,仅仅记录最后一个doc的计算值类似md5,然后每一次读取,都会如此记录最后一个值的mark,下一次通过这个mark便能快速的定位到第二页上,如此往复,便能完成整个数据的读取。而且耗费内存非常少。

假如现在有排好队的10个人等待买饭,而一个房间里面最多一次只能进2个人,那么我们就可以将这个2个人,编号顺序,1和2,他们打完饭后,让2号的人通知,下一组2个人,进来打饭,如此往复
所有人都能吃到饭,这就类似solr中游标的使用。

使用游标的方式读取数据,也有一些约束或者缺点:

(1)查询条件里面必须有cursorMark参数,而且必须不能有start参数
(2)查询的条件里必须按照主键排序(升序或降序),如果没有这个条件,主键重复,那么会造成多个游标的mark值,这样以来下一次请求就不知道如何定位了,而且有可能出现重复读数据的情况
(3)如果一个分页的系统,按照指定页码跳转的功能,这样实现的功能是实现不了的,因为游标一旦读取了,就不能再返回上一次的位置了,这种业务最好使用start+rows搞定。

solrj实现代码例子:

//游标查询
    public static void cursorQuery()throws Exception{
            //http solr服务
            HttpSolrClient sc=new HttpSolrClient("http://localhost:8983/solr/one");
            //solr查询封装
            SolrQuery sq =new SolrQuery();
                sq.setRows(2);//设置游标一次读的数量
                sq.set("q", "*:*");//按条件检索
                sq.setSort("id", ORDER.asc);//根据主键排序
                String cursorMark = CursorMarkParams.CURSOR_MARK_START;//游标初始化
                boolean done = false;
                while (!done) {
                    sq.set(CursorMarkParams.CURSOR_MARK_PARAM, cursorMark);//变化游标条件
                    QueryResponse rsp = sc.query(sq);//执行多次查询读取
                    String nextCursorMark = rsp.getNextCursorMark();//获取下次游标
                    //做一些操作数据的事    
                    for(SolrDocument sd:rsp.getResults()){
                        System.out.println(sd.get("id"));
                    }
                    //如果两次游标一样,说明数据拉取完毕,可以结束循环了
                    if (cursorMark.equals(nextCursorMark)) {
                        done = true;
                    }
                    cursorMark = nextCursorMark;
                }
                //关闭连接
                sc.close();
    }
posted on   宏宇  阅读(587)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2008-08-21 vs2005 Team System的版本
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示