46

ページネーションに必要なクエリを実装するにはどうすればよいですか?

基本的に、ページ 1 が要求されると、最初の 5 つのエントリを取得します。2 ページについては、次の 5 などを取得します。

これをcouchdb-pythonモジュール経由で使用する予定ですが、実装に違いはありません。

4

4 に答える 4

35

CouchDB ガイドには、多くのサンプル コードを含む、ページネーションに関する適切な説明があります

  • rows_per_page + 1ビューから行をリクエストする
  • 行を表示rows_per_pageし、最後の行をnext_startkey
  • ページ情報として保持startkeyし、next_startkey
  • 値を使用next_*して次のリンクを作成し、他の値を使用して前のリンクを作成します

注: CouchDB でページを取得する適切な方法は、開始キーを指定することです。ご想像のとおり、開始インデックスではありません。しかし、どのキーで 2 ページ目を開始するかをどうやって知るのでしょうか? 巧妙な解決策: 「1 ページに 10 行を要求する代わりに、11 行を要求しますが、10 行だけを表示し、11 行目の値を次のページの開始キーとして使用します。」

複数のドキュメントが同一のキーを発行することが予想される場合は、正しくページ付けするためstartdocidに加えて使用する必要があります。startkeyその理由はstartkey、行を一意に識別するには、それだけでは不十分だからです。を指定しないと、これらのパラメーターは役に立ちませんstartkey。実際、CouchDB は最初にパラメータを確認し、複数の可能性のある開始行のキーが同じでドキュメント ID が異なる場合startkey、パラメータを使用して範囲の開始をさらに再定義します。startdocidについても同じですenddocid

于 2011-06-25T01:20:33.087 に答える
13

CouchDB HTTP View APIは、ページングを効率的に行うための十分な範囲を提供します。

最も簡単な方法はとを使用startkeycountます。Countは、CouchDBがそのビューリクエストに対して返すエントリの最大数であり、設計次第です。startkeyは、CouchDBを開始する場所です。ビューをリクエストすると、エントリの数も表示されるため、ユーザーに表示したい場合は、ページ数を計算できます。

したがって、最初のリクエストでは開始キーを指定せず、表示するエントリ数のカウントのみを指定します。次に、返された最後のエントリのキーをメモし、それを次のページの開始キーとして使用できます。この単純な形式では、あるページの最後のエントリが次のページの最初のエントリであるオーバーラップが発生します。これが望ましくない場合は、ページの最後のエントリを表示しないのは簡単です。

これを行う簡単な方法は、skipパラメーターを使用してページの開始ドキュメントを作成することですが、この方法は注意して使用する必要があります。skipパラメータは、内部エンジンが反復しているエントリを返さないようにするだけです。これにより目的の動作が得られますが、ページの最初のドキュメントをキーで検索するよりもはるかに時間がかかります。スキップされるドキュメントが多いほど、リクエストは遅くなります。

于 2008-11-24T15:46:39.067 に答える
1

これは私がこれまでに思いついたことです - すべての投稿のIDを取得し、最初のx個のIDの実際のアイテムを取得します..

それほど効率的ではありませんが、すべての投稿を取得してからほとんどを破棄するよりは効率的です。とはいえ、驚いたことに、非常に高速に実行されたように見えました。このposthelper.page()メソッドを 100 回実行したところ、約 0.5 秒かかりました。

これを実際の質問に投稿したくなかったので、回答にそれほど影響を与えません-コードは次のとおりです。

allPostsUuid = """
function(doc) {
if(doc.type == 'post'){
    emit(doc._id, null);
}
}
"""

class PostsHelper:
    def __init__(self):
        server = Server(config.dbhost)
        db = server[config.dbname]
        return db


    def _getPostByUuid(self, uuid):
        return self.db.get(uuid)

    def page(self, number = 1):
        number -= 1 # start at zero offset
        start = number * config.perPage
        end = start + config.perPage

        allUuids = [
            x.key for x in self.db.query(allPostsUuid)
        ]
        ret = [
            self._getPostByUuid(x) for x in allUuids[start : end]
        ]

        if len(ret) == 0:
            raise Error404("Invalid page (%s results)" % (len(allUuids)))
        else:
            return ret
于 2008-11-23T05:41:12.440 に答える