使用Couchbase分页
如果對(duì)Couchbase集群進(jìn)行查詢(xún)時(shí)必須處理大量文檔,則使用分頁(yè)來(lái)逐頁(yè)獲取行很重要。 您可以在“ 分頁(yè) ”一章的文檔中找到一些信息,但是我想在本文中提供更多詳細(xì)信息和示例代碼。
在此示例中,我將基于啤酒樣本數(shù)據(jù)集創(chuàng)建一個(gè)簡(jiǎn)單的視圖,該視圖用于按國(guó)家/地區(qū)查找啤酒廠:
該視圖按國(guó)家列出所有啤酒廠,索引如下:
| 狂暴者 | 阿根廷 | 空值 |
| cervecera_jerome | 阿根廷 | 空值 |
| brouwerij_nacional_balashi | 阿魯巴島 | 空值 |
| australian_brewing_corporation | 澳大利亞 | 空值 |
| carlton_and_united_breweries | 澳大利亞 | 空值 |
| 庫(kù)珀釀酒廠 | 澳大利亞 | 空值 |
| 寄養(yǎng)人_s_澳大利亞_公司 | 澳大利亞 | 空值 |
| gold_coast_brewery | 澳大利亞 | 空值 |
| lion_nathan_australia_hunter_street | 澳大利亞 | 空值 |
| little_creatures_brewery | 澳大利亞 | 空值 |
| 麥芽鏟子釀酒廠 | 澳大利亞 | 空值 |
| matilda_bay_brewing | 澳大利亞 | 空值 |
| … | … | … |
| … | … | … |
| … | … | … |
| yellowstone_valley_brewing | 美國(guó) | 空值 |
| yuengling_son_brewing | 美國(guó) | 空值 |
| zea_rotisserie_and_brewery | 美國(guó) | 空值 |
| 培養(yǎng)者 | 越南 | 空值 |
| 色相釀酒 | 越南 | 空值 |
因此,現(xiàn)在您要以5行的頁(yè)面大小瀏覽此索引。
使用跳過(guò)/限制參數(shù)
最簡(jiǎn)單的方法是使用limit和skip參數(shù),例如:
頁(yè)面1:?limit = 5&skip0
頁(yè)面2:?limit = 5&skip = 5
…
頁(yè)面x:?limit = 5&skip(limit *(page-1))
很明顯,您可以使用進(jìn)行范圍或鍵查詢(xún)(startkey / endkey,鍵,鍵)和排序選項(xiàng)(降序)所需的任何其他參數(shù)。
這是簡(jiǎn)單但不是最有效的方法,因?yàn)椴樵?xún)引擎必須讀取與查詢(xún)匹配的所有行,直到達(dá)到跳過(guò)值。
python中的一些代碼示例使用此視圖進(jìn)行分頁(yè):
from couchbase import Couchbase cb = Couchbase.connect(bucket='beer-sample')hasRow = True rowPerPage = 5 page = 0 currentStartkey="" startDocId=""while hasRow :hasRow = Falseskip = 0 if page == 0 else 1page = page + 1print "-- Page %s --" % (page)rows = cb.query("test", "by_country", limit=rowPerPage, skip=skip, startkey=currentStartkey, startkey_docid=startDocId)for row in rows:hasRow = Trueprint "Country: \"%s\" \t Id: '%s'" % (row.key, row.docid)currentStartkey = row.keystartDocId = row.docidprint " -- -- -- -- \n"該應(yīng)用程序在所有頁(yè)面上循環(huán),直到索引結(jié)束。
正如我之前所說(shuō),這不是最佳方法,因?yàn)橄到y(tǒng)必須讀取所有值,直到達(dá)到跳過(guò)為止。 以下示例顯示了解決此問(wèn)題的更好方法。
使用startkey / startkey_docid參數(shù)
為了使這種分頁(yè)更加有效,可以采用另一種方法。 此方法使用startkey和startkey_docid選擇適當(dāng)?shù)奈臋n。
- startkey參數(shù)將是查詢(xún)應(yīng)開(kāi)始讀取的鍵的值(基于“上一頁(yè)”的最后一個(gè)鍵)
- 由于對(duì)于例如“ Germany”的鍵,您可能具有一個(gè)或多個(gè)ID(文檔),因此有必要對(duì)Couchbase查詢(xún)引擎說(shuō)從哪里開(kāi)始,為此,您需要使用startkey_docid參數(shù),并忽略此ID,因?yàn)樗乔耙豁?yè)的最后一個(gè)。
因此,如果我們查看索引,并添加一個(gè)行號(hào)來(lái)說(shuō)明分頁(yè)
| 查詢(xún)第1頁(yè) 極限= 5 | ||||
| 1個(gè) | 狂暴者 | 阿根廷 | 空值 | |
| 2 | cervecera_jerome | 阿根廷 | 空值 | |
| 3 | brouwerij_nacional_balashi | 阿魯巴島 | 空值 | |
| 4 | australian_brewing_corporation | 澳大利亞 | 空值 | |
| 5 | carlton_and_united_breweries | 澳大利亞 | 空值 | |
| ||||
| 6 | 庫(kù)珀釀酒廠 | 澳大利亞 | 空值 | |
| 7 | 寄養(yǎng)人_s_澳大利亞_公司 | 澳大利亞 | 空值 | |
| 8 | gold_coast_brewery | 澳大利亞 | 空值 | |
| 9 | lion_nathan_australia_hunter_street | 澳大利亞 | 空值 | |
| 10 | little_creatures_brewery | 澳大利亞 | 空值 | |
查詢(xún)第3頁(yè)
| ||||
| 11 | 麥芽鏟子釀酒廠 | 澳大利亞 | 空值 | |
| 12 | matilda_bay_brewing | 澳大利亞 | 空值 | |
| … | … | … | ||
| … | … | … | ||
| … | … | … | ||
| … | yellowstone_valley_brewing | 美國(guó) | 空值 | |
| … | yuengling_son_brewing | 美國(guó) | 空值 | |
| … | zea_rotisserie_and_brewery | 美國(guó) | 空值 | |
| … | 培養(yǎng)者 | 越南 | 空值 | |
| … | 色相釀酒 | 越南 | 空值 |
因此,如您在上面的示例中看到的那樣,查詢(xún)使用startkey和文檔ID,并使用skip = 1傳遞它。
現(xiàn)在,讓我們?cè)俅问褂肞ython查看應(yīng)用程序代碼
from couchbase import Couchbase cb = Couchbase.connect(bucket='beer-sample')hasRow = True rowPerPage = 5 page = 0 currentStartkey="" startDocId=""while hasRow :hasRow = Falseskip = 0 if page == 0 else 1page = page + 1print "-- Page %s --" % (page)rows = cb.query("test", "by_country", limit=rowPerPage, skip=skip, startkey=currentStartkey, startkey_docid=startDocId)for row in rows:hasRow = Trueprint "Country: \"%s\" \t Id: '%s'" % (row.key, row.docid)currentStartkey = row.keystartDocId = row.docidprint " -- -- -- -- \n"該應(yīng)用程序在所有頁(yè)面上循環(huán),直到索引結(jié)束
使用這種方法,應(yīng)用程序開(kāi)始在特定鍵(startkey參數(shù))處讀取索引,并且僅在索引中的必要條目上循環(huán)。 這比使用簡(jiǎn)單的跳過(guò)方法更有效。
具有減少功能的視圖
當(dāng)您的視圖使用reduce函數(shù)進(jìn)行分組時(shí),無(wú)法使用參數(shù)startkey_docid,因?yàn)樵诳s小結(jié)果時(shí)文檔的ID不可用。
因此,在使用reduce時(shí),必須使用skip和limit參數(shù)。
Couchbase Java SDK分頁(yè)器
在前面的示例中,我展示了如何使用各種查詢(xún)參數(shù)進(jìn)行分頁(yè)。 Java SDK提供了一個(gè)Paginator對(duì)象,以幫助開(kāi)發(fā)人員處理分頁(yè)。 以下示例在Paginator API中使用相同的視圖。
package com.couchbase.devday;import com.couchbase.client.CouchbaseClient; import com.couchbase.client.protocol.views.*; import java.net.URI; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Properties; import java.util.concurrent.TimeUnit; import java.util.logging.ConsoleHandler; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger;public class JavaPaginatorSample {public static void main(String[] args) {configure();System.out.println("--------------------------------------------------------------------------");System.out.println("\tCouchbase - Paginator");System.out.println("--------------------------------------------------------------------------");List<URI> uris = new LinkedList<URI>();uris.add(URI.create("http://127.0.0.1:8091/pools"));CouchbaseClient cb = null;try {cb = new CouchbaseClient(uris, "beer-sample", "");System.out.println("--------------------------------------------------------------------------");System.out.println("Breweries (by_name) with docs & JSON parsing");View view = cb.getView("test", "by_country");Query query = new Query();int docsPerPage = 5;Paginator paginatedQuery = cb.paginatedQuery(view, query, docsPerPage);int pageCount = 0;while(paginatedQuery.hasNext()) {pageCount++;System.out.println(" -- Page "+ pageCount +" -- ");ViewResponse response = paginatedQuery.next();for (ViewRow row : response) {System.out.println(row.getKey() + " : " + row.getId());}System.out.println(" -- -- -- ");}System.out.println("\n\n");cb.shutdown(10, TimeUnit.SECONDS);} catch (Exception e) {System.err.println("Error connecting to Couchbase: " + e.getMessage());} }private static void configure() {for(Handler h : Logger.getLogger("com.couchbase.client").getParent().getHandlers()) {if(h instanceof ConsoleHandler) {h.setLevel(Level.OFF);}}Properties systemProperties = System.getProperties();systemProperties.put("net.spy.log.LoggerImpl", "net.spy.memcached.compat.log.SunLogger");System.setProperties(systemProperties);Logger logger = Logger.getLogger("com.couchbase.client");logger.setLevel(Level.OFF);for(Handler h : logger.getParent().getHandlers()) {if(h instanceof ConsoleHandler){h.setLevel(Level.OFF);}} }}如您所見(jiàn),您可以使用Java Paginator輕松對(duì)查詢(xún)結(jié)果進(jìn)行分頁(yè)。
- 在第37行,使用視圖和查詢(xún)對(duì)象創(chuàng)建Paginator,并指定頁(yè)面大小
- 然后,您只需要使用hasNext()和next()方法來(lái)導(dǎo)航結(jié)果。
Java Paginator知道他們的查詢(xún)使用的是減少還是不使用,因此您可以將其與所有類(lèi)型的查詢(xún)一起使用–在內(nèi)部,它將在跳過(guò)/限制方法和doc_id方法之間切換。 您可以在Paginator類(lèi)中看到它是如何完成的 。
請(qǐng)注意,如果要在HTTP請(qǐng)求之間的Web應(yīng)用程序中執(zhí)行此操作,則必須將Paginator對(duì)象保留在用戶(hù)會(huì)話中,因?yàn)楫?dāng)前API會(huì)將當(dāng)前頁(yè)面保持在其狀態(tài)。
結(jié)論
在此博客文章中,您學(xué)習(xí)了如何在Couchbase視圖中處理分頁(yè)。 總結(jié)
- 分頁(yè)基于您在執(zhí)行查詢(xún)時(shí)發(fā)送的某些特定參數(shù)。
- Java開(kāi)發(fā)人員可以使用簡(jiǎn)化分頁(yè)的Paginator類(lèi)。
我邀請(qǐng)您查看仍在開(kāi)發(fā)中的新Couchbase查詢(xún)語(yǔ)言N1QL,它將使用LIMIT&OFFSET參數(shù)為開(kāi)發(fā)人員提供更多選項(xiàng),包括分頁(yè),例如:
SELECT fname, age FROM tutorialWHERE age > 30LIMIT 2OFFSET 2如果您想了解有關(guān)N1QL的更多信息:
- Couchbase社區(qū)門(mén)戶(hù)上的N1QL
- N1QL在線教程
翻譯自: https://www.javacodegeeks.com/2013/10/pagination-with-couchbase.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的使用Couchbase分页的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: (ddos vip)
- 下一篇: Apache Camel简介