`
eksliang
  • 浏览: 598977 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Solr Deep Paging(solr 深分页)

    博客分类:
  • solr
阅读更多

转载请出自出处: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/

 

 

分享到:
评论
2 楼 eksliang 2015-01-19  
你往下面点击翻页的时候,肯定是保证条件一致的情况啊!如果条件不同就不是同一次查询了。
1 楼 qindongliang1922 2015-01-12  
写的很不错,请问一下,楼主测试的深度分页,只能顺序的根据页码翻页吗,还是说,可以任意加上查询条件,意思,看你下面代码的setQuery这个条件,你写的是*:*,查询所有,如果每一次查询条件都不一样,翻页时候,是否会有问题。
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);  
        }         
    }  

相关推荐

    solr搜索引擎支持分页

    5. 跳跃分页(Deep Paging): 当数据量巨大时,传统的分页方法可能会遇到性能问题,因为每次请求都需要计算总结果数。Solr提供了一种跳转分页的方式,即通过`fq`参数配合`cache`和`query`,避免计算所有结果,从而...

    Apache Solr(solr-8.11.1.zip)

    Apache Solr是一款开源的企业级搜索平台,由Apache软件基金会维护。它是基于Java的,提供了高效、可扩展的全文检索、数据分析和分布式搜索功能。Solr-8.11.1是该软件的一个特定版本,包含了从早期版本到8.11.1的所有...

    基于java-solr-geo空间坐标搜索、距离排序、分页

    基于solr-geo空间搜索 1、Solr的schema.xml配置 定义坐标field 2、Solr的data-config.xml配置 建立索引 3、java查询语法 坐标距离、分页、排序

    solr(solr-9.0.0.tgz)

    Solr,全称为Apache Solr,是Apache软件基金会的一个开源项目,主要用来处理全文搜索和企业级的搜索应用。它基于Java,利用Lucene库构建,提供了高效、可扩展的搜索和导航功能。Solr-9.0.0是该软件的最新版本,此...

    Apache Solr(solr-8.11.1.tgz)

    Apache Solr 是一个开源的全文搜索引擎,由Apache软件基金会维护,是Lucene项目的一部分。它提供了高效、可扩展的搜索和导航功能,广泛应用于企业级的搜索应用中。Solr-8.11.1是该软件的一个特定版本,包含了最新的...

    solr4.7服务搭建

    ### Solr 4.7 服务搭建详细指南 #### 一、环境准备 为了搭建 Solr 4.7 服务,我们需要确保以下环境已经准备好: 1. **Java Development Kit (JDK) 1.7**:Solr 需要 Java 运行环境支持,这里我们选择 JDK 1.7 ...

    java进阶Solr从基础到实战

    在本套课程中,我们将全面的讲解Solr,从Solr基础到Solr高级,再到项目实战,基本上涵盖了Solr中所有的知识点。 主讲内容 章节一:Solr基础(上) 1. 环境搭建 2. 核心讲解 3. 数据导入 4. 各种中文分析器 章节二:...

    solr(solr-9.0.0-src.tgz)源码

    Solr是Apache软件基金会的一个开源项目,它是基于Java的全文搜索服务器,被广泛应用于企业级搜索引擎的构建。源码分析是深入理解一个软件系统工作原理的重要途径,对于Solr这样的复杂系统尤其如此。这里我们将围绕...

    solr-6.2.0源码

    Solr是Apache软件基金会开发的一款开源全文搜索引擎,它基于Java平台,是Lucene的一个扩展,提供了更为方便和强大的搜索功能。在Solr 6.2.0版本中,这个强大的分布式搜索引擎引入了许多新特性和改进,使其在处理大...

    解决solr启动404问题

    Solr是Apache Lucene项目的一个子项目,是一个高性能、基于Java的企业级全文搜索引擎服务器。当你在尝试启动Solr时遇到404错误,这通常意味着Solr服务没有正确地启动或者配置文件设置不正确。404错误表示“未找到”...

    solr增量更新架包apache-solr-dataimportscheduler.jar

    Apache Solr 是一个开源的全文搜索引擎,广泛应用于各种企业级数据搜索和分析场景。增量更新是Solr的一个关键特性,它允许系统仅处理自上次完整索引以来发生更改的数据,从而提高了性能并降低了资源消耗。"apache-...

    ikanalyzer-solr8.4.0_solr8_solr_ikanalyzer_中文分词_

    Solr8.4.0 是 Apache Solr 的一个版本,这是一个高度可配置、高性能的全文搜索和分析引擎,广泛用于构建企业级搜索应用。 在 Solr 中,ikanalyzer 是一个重要的组件,它通过自定义Analyzer来实现中文的分词处理。...

    solr.war包solr.war包solr.war包solr.war包solr.war包

    solr.warsolr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包solr.war包...

    solr-dataimport-scheduler.jar 可使用于solr7.x版本

    Solr 数据导入调度器(solr-dataimport-scheduler.jar)是一个专门为Apache Solr 7.x版本设计的组件,用于实现数据的定期索引更新。在理解这个知识点之前,我们需要先了解Solr的基本概念以及数据导入处理...

    solr的学习

    ### Solr 学习知识点详解 #### 一、Solr 概述 - **定义**:Solr 是 Apache 下的一个顶级开源项目,采用 Java 开发,它是基于 Lucene 的全文搜索服务器。Solr 可以独立运行在 Jetty、Tomcat 等 Servlet 容器中。 -...

    solr-7.4.0.zip

    Solr,全称为Apache Solr,是一款开源的企业级全文搜索引擎,由Apache软件基金会开发并维护。它是基于Java的,因此在使用Solr之前,确保你的系统已经安装了Java 8或更高版本是至关重要的。标题"solr-7.4.0.zip"表明...

    Linux上Solr的启动方式

    使用Solr内置的Jetty服务器启动Solr (1)借助X Shell上传solr的安装包到/usr/local/目录下,使用 tar -zxvf命令进行解压.  (2)使用内置的Jetty来启动Solr服务器只需要在example目录下,执行start.jar程序即可,...

    solr-4.4.0.tgz

    Solr 是一个开源的全文搜索引擎,由 Apache 软件基金会开发。版本 4.4.0 是 Solr 的一个重要里程碑,它包含了丰富的特性和改进。这个“solr-4.4.0.tgz”文件是一个针对 Linux 系统的压缩包,用于在服务器上部署 Solr...

    solr定时自动同步数据库需要用到的apache-solr-dataimportscheduler.jar包

    Apache Solr是一款强大的开源搜索引擎,它能够高效地处理和索引大量数据,提供快速的全文检索、 faceting、高亮显示等高级功能。在实际应用中,为了保持搜索结果的实时性,我们往往需要将数据库中的数据实时或定时...

    solr服务器_solr_

    Solr服务器是Apache Lucene项目的一个子项目,是一款开源的企业级搜索平台,专门用于处理大量文本数据的全文检索、搜索和分析。它基于Java开发,能够处理多种数据源,包括XML、JSON、CSV等,提供了高效、可扩展的...

Global site tag (gtag.js) - Google Analytics