9

データストアのシンプルさ、スケーラビリティ、使いやすさが気に入っています。そして、新しいndbライブラリに見られる拡張機能は素晴らしいものです。

データストアのベスト プラクティスを理解しているので、クエリに一致するアイテムの数が多い場合、一致するクエリ結果のアイテム数やページ数を提供するコードを記述しないでください。これを行う唯一の方法は、リソースを集中的に使用するすべての結果を取得することです。

ただし、私たちのアプリケーションを含む多くのアプリケーションでは、一致するアイテムの数を確認し、ユーザーがそれらの結果の特定のページに移動できるようにすることが一般的に望まれます。データストアのページングの問題は、大きなデータセットを介したページングの記事で概説されているように、fetch(limit, offset=X)の制限を回避する必要があるため、さらに複雑になります。. 推奨されるアプローチをサポートするには、結果が表示される方法で順序付けできる一意の値を持つ列がデータに含まれている必要があります。この列は、結果の各ページの開始値を定義します。それを保存すると、対応するページを効率的に取得でき、要求に応じて特定のページまたは次のページに移動できます。したがって、複数の方法で並べ替えられた結果を表示する場合は、そのような列をいくつか維持する必要がある場合があります。

SDK v1.3.1 の時点で、クエリ カーソルはデータストアのページングを行うための推奨される方法であることに注意してください。IN および != フィルター演算子がサポートされていないなど、いくつかの制限があります。現在、重要なクエリのいくつかはINを使用していますが、クエリ カーソルで使用するためにORを使用して記述してみます。

提案されたガイドラインに従って、ユーザーには(次へ)および(前へ)ナビゲーション ボタンと、ナビゲーションが進むにつれて特定のページ ボタンが与えられます。たとえば、ユーザーが(次へ)を 3 回押した場合、アプリは次のボタンを表示し、それぞれの一意の開始レコードまたはカーソルを記憶して、効率的なナビゲーションを維持できます。(前) (ページ-1) (ページ-2) (ページ) -3) (Page-4) (次へ) .

カウントを個別に追跡することを提案する人もいますが、返される結果が異なる豊富なフィールド セットに対してユーザーがクエリを実行できる場合、この方法は実用的ではありません。

これらの問題全般と、具体的には次の質問に関する洞察を探しています。

  1. これらの制限を回避するために、データストア アプリでクエリ結果のどのようなナビゲーション オプションを提供していますか?

  2. ユーザーに効率的な結果カウントとクエリ結果セット全体のページ ナビゲーションを提供することが優先事項である場合は、現在提供されているGAE MySql ソリューションを優先して、データストアの使用を放棄する必要があります。

  3. ビッグ テーブル アーキテクチャまたはデータストアの実装に、クエリの結果を効率的にカウントするための追加機能を提供する今後の変更はありますか?

ご協力いただきありがとうございます。

4

4 に答える 4

2

それはすべて、通常得られる結果の数によって異なります。たとえば、.count() に適切な制限を渡すことで、#items がたとえば <= 100 の場合は正確な数を提供でき、それ以上の場合は「多数」を提供できます。考えられるすべてのカウントを事前に計算することはできないようですが、少なくともそれらをキャッシュして、多くのデータストア操作を節約できます。

NDB を使用する場合、最も効率的な方法は、fetch_page() を使用してエンティティの最初のページを要求し、結果のカーソルを count() 呼び出しの開始点として使用することです。または、非同期機能を使用して、最初のページの fetch() と count() を同時に実行する方がよい場合があります。クエリがカーソルをサポートしていない場合は、2 番目のオプションが唯一の選択肢となる場合があります。現在、ほとんどの IN / OR クエリはカーソルをサポートしていませんが、__key__.

UI オプションに関しては、次のページと前のページのオプションを提供するだけで十分だと思います。数ページ飛ばしできる「グーーーーグル」UIはかわいいのですが、自分ではほとんど使っていません。(「前のページ」を実装するには、クエリの順序を逆にして、現在のページに使用したのと同じカーソルを使用します。これは動作することが保証されています。)

于 2012-02-23T05:06:22.630 に答える
1

たぶん、このスタイルのページングを目指してください:

(最初)(前)(ページ 1 )(ページ 2)(ページ 3)...(最後)(次)

そうすれば、合計数は必要ありません。別の 3 つ以上のページに十分な結果があることをコードで知るだけで済みます。1 ページあたり 10 アイテムのページ サイズで、30 以上のアイテムがあることを知る必要があります。

60 個のアイテム (6 ページ分) がある場合、既に 4 ページ目にいる場合、コードは先を見越して、あと 20 レコードしか残っていないことを認識するので、最後のページ番号を表示できます。

(最初)(前)(ページ4 )(ページ5)(ページ6)(次)(最後)

基本的に、現在のページのフェッチごとに、別の 3 ページのデータに十分なレコードをフェッチし、それらを数えて実際にあと何ページあるかを確認し、それに応じてページャーを表示します。

また、余分なアイテムをフェッチするよりも、キーだけをフェッチする方が効率的です。それが意味をなすことを願っています!!?? :)

于 2012-02-28T14:47:43.917 に答える
0

質問は「ページを提供するためのアイデア/代替案を探している」というものだったので、10 ページ分の key_only アイテムをフェッチするという非常に単純な代替案であり、このセット内でのナビゲーションを処理することを検討する価値があります。

同様の質問に答える際にこれについて詳しく説明しました。そこにサンプルコードがあります:

カーソルを使用した後方ページ付けは機能していますが、アイテムがありません

この質問には、サンプル コードの方が適しています。ここにその一部があります:

def session_list():
    page = request.args.get('page', 0, type=int)

    sessions_keys = Session.query().order(-Session.time_opened).fetch(100, keys_only=True)
    sessions_keys, paging = generic_list_paging(sessions_keys, page)
    # generic_list_paging will select the proper sublist.
    sessions = [ sk.get() for sk in sessions_keys ]

    return render_template('generic_list.html', objects=sessions, paging=paging)

詳細なコードについては、参照されている質問を参照してください。

もちろん、結果セットが巨大になる可能性がある場合でも、フェッチに何らかの制限を与える必要があります。ハード リミットは 1000 アイテムだと思います。明らかに、結果が 10 ページを超える場合、ユーザーは基準を追加して絞り込むように求められます。

数百の keys_only アイテム内でページングを処理することは、非常に簡単であるため、検討する価値があります。質問で述べたように、直接のページ ナビゲーションを提供することが非常に簡単になります。実際のエンティティ項目は実際の現在のページに対してのみフェッチされ、残りはキーのみであるため、それほどコストはかかりません。また、keys_only の結果セットを memcache に数分間保持することを検討すると、ユーザーがページをすばやくブラウジングするときに同じクエリを再度実行する必要がなくなります。

于 2015-04-10T15:04:42.713 に答える
0
  1. gmail はいくつかのカウントで準備ができていることに気付きました - 受信したメールの合計数、受信トレイにあるメールの数などを表示できますが、他のカウントでは、全文検索のように、あなたが見ていると表示されます「多数の 1-20」または「約 130 の 1-20」。本当にすべてのクエリのカウントを表示する必要がありますか? それとも、重要なものだけを事前に計算できますか?
于 2012-02-22T17:32:18.103 に答える