Solr游标查询提高翻页效率

Solr游标查询提高翻页效率

长期以来,我们一直有一个深分页问题。如果直接跳到很靠后的页数,查询速度会比较慢。这是因为 Solr 需要为查询从开始遍历所有数据。直到 Solr 4.7 这个问题一直没有一个很好的解决方案。在最近发布的 Solr 版本中,Solr 使用了所谓的游标大幅度提高深翻页的性能。

问题

深分页的问题是很清楚的。Solr 必须为返回的搜索结果准备一个列表,并返回它的一部分。如果该部分来源于该列表的前面并不难。但如果我们想返回第 10000 页(每页 20 条记录)的数据,Solr 需要准备一个包含大小为 200000(10000 * 20)的列表。这样,它不仅需要时间,还需要内存。

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

用法

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

查询

我们从一个简单的查询开始:

1
curl 'localhost:8983/solr/select?q=*:*&rows=1&sort=score+desc,id+asc&cursorMark=*'

这里我们传入一个 cursorMark=* 参数,告诉 Solr,我们要使用游标。

搜索结果

上面的查询将返回以下搜索结果:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">33</int>
<lst name="params">
<str name="sort">score desc,id asc</str>
<str name="start">0</str>
<str name="q">*:*</str>
<str name="cursorMark">*</str>
<str name="rows">1</str>
</lst>
</lst>
<result name="response" numFound="32" start="0">
<doc>
<str name="id">0579B002</str>
<str name="name">Canon PIXMA MP500 All-In-One Photo Printer</str>
<str name="manu">Canon Inc.</str>
<str name="manu_id_s">canon</str>
<arr name="cat">
<str>electronics</str>
<str>multifunction printer</str>
<str>printer</str>
<str>scanner</str>
<str>copier</str>
</arr>
<arr name="features">
<str>Multifunction ink-jet color photo printer</str>
<str>Flatbed scanner, optical scan resolution of 1,200 x 2,400 dpi</str>
<str>2.5" color LCD preview screen</str>
<str>Duplex Copying</str>
<str>Printing speed up to 29ppm black, 19ppm color</str>
<str>Hi-Speed USB</str>
<str>memory card: CompactFlash, Micro Drive, SmartMedia, Memory Stick, Memory Stick Pro, SD Card, and MultiMediaCard</str>
</arr>
<float name="weight">352.0</float>
<float name="price">179.99</float>
<str name="price_c">179.99,USD</str>
<int name="popularity">6</int>
<bool name="inStock">true</bool>
<str name="store">45.19214,-93.89941</str>
<long name="_version_">1461375031699308544</long>
</doc>
</result>
<str name="nextCursorMark">AoIIP4AAACgwNTc5QjAwMg==</str>
</response>

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

下一个查询

提交下面这个查询看一下:

1
curl 'localhost:8983/solr/select?q=*:*&rows=1&sort=score+desc,id+asc&cursorMark=AoIIP4AAACgwNTc5QjAwMg=='

结果如下:

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
32
33
34
35
36
37
38
39
40
41
42
<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">2</int>
<lst name="params">
<str name="sort">score desc,id asc</str>
<str name="indent">true</str>
<str name="q">*:*</str>
<str name="cursorMark">AoIIP4AAACgwNTc5QjAwMg==</str>
<str name="rows">1</str>
</lst>
</lst>
<result name="response" numFound="32" start="0">
<doc>
<str name="id">100-435805</str>
<str name="name">ATI Radeon X1900 XTX 512 MB PCIE Video Card</str>
<str name="manu">ATI Technologies</str>
<str name="manu_id_s">ati</str>
<arr name="cat">
<str>electronics</str>
<str>graphics card</str>
</arr>
<arr name="features">
<str>ATI RADEON X1900 GPU/VPU clocked at 650MHz</str>
<str>512MB GDDR3 SDRAM clocked at 1.55GHz</str>
<str>PCI Express x16</str>
<str>dual DVI, HDTV, svideo, composite out</str>
<str>OpenGL 2.0, DirectX 9.0</str>
</arr>
<float name="weight">48.0</float>
<float name="price">649.99</float>
<str name="price_c">649.99,USD</str>
<int name="popularity">7</int>
<bool name="inStock">false</bool>
<date name="manufacturedate_dt">2006-02-13T00:00:00Z</date>
<str name="store">40.7143,-74.006</str>
<long name="_version_">1461375031846109184</long>
</doc>
</result>
<str name="nextCursorMark">AoIIP4AAACoxMDAtNDM1ODA1</str>
</response>

现在,返回的 nextCursorMark 变化了,这是新的游标。

进一步查询

接下来的查询就很清楚了,使用 cursorMark 参数不断翻页,再来一次:

1
curl 'localhost:8983/solr/select?q=*:*&rows=1&sort=score+desc,id+asc&cursorMark=AoIIP4AAACoxMDAtNDM1ODA1'

总结

Solr 4.7 引入的这个游标参数非常简单,大大提升了翻页的效果。

详细的测试报告请参考: http://searchhub.org/2013/12/12/coming-soon-to-solr-efficient-cursor-based-iteration-of-large-result-sets

© 2025 Solr Community of China All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero