文档章节

Solr Deep Paging(solr 深分页)

闪电
 闪电
发布于 2015/05/09 23:32
字数 1059
阅读 69
收藏 0

转载请出自出处:http://eksliang.iteye.com/blog/2148370

作者:eksliang(ickes) blg:http://eksliang.iteye.com/

概述

长期以来,我们一直有一个深分页问题。如果直接跳到很靠后的页数,查询速度会比较慢。这是因为Solr的需要为查询从开始遍历所有数据。直到Solr的4.7这个问题一直没有一个很好的解决方案。直到solr4.7引入了游标才解决这个问题。

 

问题

深分页的问题是很清楚。Solr必须为返回的搜索结果准备一个列表,并返回它的一部分。如果该部分来源于该列表的前面并不难。但如果我们想返回第10000页(每页20条记录)的数据,Solr需要准备一个包含大小为200000(10000 * 20)的列表。这样,它不仅需要时间,还需要内存。像我们现在生产上的历史数据达到了6个亿的数据,如果直接跳转到最后一页,必定内存溢出。

 

solr4.7是怎么解决这个问题的?

答:Solr 4.7的发布改变了这一状况,引入了游标的概念。游标是一个动态结构,不需要存储在服务器上。游标包含了查询的结果的偏移量,因此,Solr的不再需要每次从头开始遍历结果直到我们想要的记录,游标的功能可以大幅提升深翻页的性能。

 

用法

游标的使用非常简单。在第一个查询中,我们需要传递一个额外的参数- cursorMark = *,告诉Solr返回游标。在返回中除了搜索结果,我们还可以得到nextCursorMark信息。看看下面这个例子。

http://192.168.238.133:8080/solr/collection1/select?q=*:*&rows=3&sort=price desc,id asc&cursorMark=*

 返回结果如下:

 

<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">186</int>
<lst name="params">
<str name="sort">price desc,id asc</str>
<str name="q">*:*</str>
<str name="cursorMark">*</str>
<str name="rows">3</str>
</lst>
</lst>
<result name="response" numFound="4160002" start="0">
<doc>
<str name="id">a004180000</str>
<str name="name">ickes_4180000</str>
<float name="price">5180000.0</float>
<str name="price_c">5180000.0,USD</str>
<str name="url">www.eksliang.iteye4180000</str>
<long name="_version_">1483095619858857993</long>
</doc>
<doc>
<str name="id">a004179999</str>
<str name="name">ickes_4179999</str>
<float name="price">5179999.0</float>
<str name="price_c">5179999.0,USD</str>
<str name="url">www.eksliang.iteye4179999</str>
<long name="_version_">1483095619858857992</long>
</doc>
<doc>
<str name="id">a004179998</str>
<str name="name">ickes_4179998</str>
<float name="price">5179998.0</float>
<str name="price_c">5179998.0,USD</str>
<str name="url">www.eksliang.iteye4179998</str>
<long name="_version_">1483095619858857991</long>
</doc>
</result>
<str name="nextCursorMark">AoIISp4UvCphMDA0MTc5OTk4</str>
</response>
 

 

   我们看到,除了平时返回的结果外,还多了一个游标数据nextCursorMark,使用这个值作为我们翻下一页的参数。

在这个基础上要得到下一页数据怎么办:让cursorMark的值等于上次返回的nextCursorMark

例如现在的下一页是这样的

http://192.168.238.133:8080/solr/collection1/select?q=*:*&rows=3&sort=price desc,id asc&cursorMark=AoIISp4UvCphMDA0MTc5OTk4

 这个时候就可以得到下一页的数据,数据如下:

<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">234</int>
<lst name="params">
<str name="sort">price desc,id asc</str>
<str name="q">*:*</str>
<str name="cursorMark">AoIISp4UvCphMDA0MTc5OTk4</str>
<str name="rows">3</str>
</lst>
</lst>
<result name="response" numFound="4160002" start="0">
<doc>
<str name="id">a004179997</str>
<str name="name">ickes_4179997</str>
<float name="price">5179997.0</float>
<str name="price_c">5179997.0,USD</str>
<str name="url">www.eksliang.iteye4179997</str>
<long name="_version_">1483095619858857990</long>
</doc>
<doc>
<str name="id">a004179996</str>
<str name="name">ickes_4179996</str>
<float name="price">5179996.0</float>
<str name="price_c">5179996.0,USD</str>
<str name="url">www.eksliang.iteye4179996</str>
<long name="_version_">1483095619858857989</long>
</doc>
<doc>
<str name="id">a004179995</str>
<str name="name">ickes_4179995</str>
<float name="price">5179995.0</float>
<str name="price_c">5179995.0,USD</str>
<str name="url">www.eksliang.iteye4179995</str>
<long name="_version_">1483095619858857988</long>
</doc>
</result>
<str name="nextCursorMark">AoIISp4UtiphMDA0MTc5OTk1</str>
</response>

 这个时候进一步查询就变得相当简单了,直接

http://192.168.238.133:8080/solr/collection1/select?q=*:*&rows=3&sort=price desc,id asc&cursorMark=AoIISp4UtiphMDA0MTc5OTk1

 

solrj对Solr Deep Paging的支持

直接上代码 

static void deepPaging() throws SolrServerException{
		HttpSolrServer server = new HttpSolrServer("http://192.168.238.133:8080/solr/collection1");
		server.setSoTimeout(10000);
		server.setConnectionTimeout(10000);
		server.setDefaultMaxConnectionsPerHost(12);
		server.setAllowCompression(true);
		SolrQuery query = new SolrQuery();
	    query.setQuery( "*:*" );
	    query.setRows(4);
	    query.addSort("price",ORDER.desc).addSort("id", ORDER.desc);
	    query.set(CursorMarkParams.CURSOR_MARK_PARAM, "*");
	    QueryResponse rsp = server.query( query );
	    List<CursorMark> beans = rsp.getBeans(CursorMark.class);
	    System.out.println(rsp.getNextCursorMark());//得到下一个游标
		for (CursorMark cursorMark : beans) {
			System.out.println(cursorMark);
		}		
	}

 返回结果如下:

AoIISp4UuiphMDA0MTc5OTk3
CursorMark [id=a004180000, name=ickes_4180000, price=5180000.0, url=www.eksliang.iteye4180000]
CursorMark [id=a004179999, name=ickes_4179999, price=5179999.0, url=www.eksliang.iteye4179999]
CursorMark [id=a004179998, name=ickes_4179998, price=5179998.0, url=www.eksliang.iteye4179998]
CursorMark [id=a004179997, name=ickes_4179997, price=5179997.0, url=www.eksliang.iteye4179997]

 

 

   参考:http://solr.pl/en/2014/03/10/solr-4-7-efficient-deep-paging/

 

 

本文转载自:http://eksliang.iteye.com/blog/2148370

闪电
粉丝 75
博文 392
码字总数 6789
作品 0
海淀
技术主管
私信 提问
Apache Solr 4.10.3 发布,开源的企业级搜索服务器

Apache Solr 4.10.3 发布,该版本修复了 21 个 bug,同时修复了 Lucene 4.10.3 中的 12 个 bug 。 Bug 修复: SOLR-6696: bin/solr start script should not enable autoSoftCommit by defau......

oschina
2015/04/09
1K
2
使用SSM+Solr优雅的实现电商项目中的搜索功能

在学习了Redis&Spring-Data-Redis入门和Solr&Spring-Data-Solr入门后,接下来就该是项目实战了。这次我们用Vue.JS和ElementUI写前端页面,优雅的整合SSM-Shiro-Redis-Solr框架。 手摸手教你优...

TyCoding
2018/09/25
385
0
Lucene 3.5和Solr 3.5:大幅降低内存用量、SearcherManager和深度分页支持

Lucene项目管理委员会宣布Apache Lucene 3.5.0和Apache Solr 3.5.0已经可以使用。Lucene是一个高性能、支持全文搜索的文本搜索开发库。Solr是一个独立的搜索服务器,其核心使用了Lucene来做索...

墙头草
2012/02/03
3.6K
7
玩转Apache Solr 6.5.1

以下都是基于linux环境 参考链接:http://lucene.apache.org/solr/quickstart.html 目录: solr 基本命令总结 solr 命令参数详解 solr 查询语法详解 solr schema配置详解 1. solr基本命令总结...

㭍葉
2017/05/31
0
0
solr查询问题 javabin

上面是具体的代码。 因为考虑到分页问题,所以想solr返回的数据格式是json。设置如下: 设置并没有效果。 输出responseHander的内容是: 发现wt内容是javabin,这是什么原因? 大家使用solr时...

杀丶破狼
2015/01/14
869
5

没有更多内容

加载失败,请刷新页面

加载更多

如何编写高质量的 JS 函数(1) -- 敲山震虎篇

本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/7lCK9cHmunvYlbm7Xi7JxQ 作者:杨昆 一千个读者,有一千个哈姆雷特。 此系列文章将会从函数的执行机制、鲁棒性、函...

vivo互联网技术
50分钟前
5
0
学会这5个Excel技巧,让你拒绝加班

在网上,随处都可以看到Excel技巧,估计已看腻了吧?但下面5个Excel技巧会让你相见恨晚。关键的是它们个个还很实用 图一 技巧1:快速删除边框 有时当我们处理数据需要去掉边框,按Ctrl+Shif...

干货趣分享
今天
11
0
JS基础-该如何理解原型、原型链?

JS的原型、原型链一直是比较难理解的内容,不少初学者甚至有一定经验的老鸟都不一定能完全说清楚,更多的"很可能"是一知半解,而这部分内容又是JS的核心内容,想要技术进阶的话肯定不能对这个...

OBKoro1
今天
10
0
高防CDN的出现是为了解决网站的哪些问题?

高防CDN是为了更好的服务网络而出现的,是通过高防DNS来实现的。高防CDN是通过智能化的系统判断来路,再反馈给用户,可以减轻用户使用过程的复杂程度。通过智能DNS解析,能让网站访问者连接到...

云漫网络Ruan
今天
15
0
OSChina 周一乱弹 —— 熟悉的味道,难道这就是恋爱的感觉

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @xiaoshiyue :好久没分享歌了分享张碧晨的单曲《今后我与自己流浪》 《今后我与自己流浪》- 张碧晨 手机党少年们想听歌,请使劲儿戳(这里)...

小小编辑
今天
3.3K
25

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部