2016-05-11 12 views
1

、私はこのクエリを持っています。これまでのところは良い、データが返さNDBカーソルは一部のクエリデータを記憶していませんか?だから、

results, cursor, more = MyModel.query(
    ancestor=mykey, 
).order(-MyModel.time).fetch_page(20) 

等結構ですそれでは、いくつかのより多くを取得しましょう、ならない我々は?これだけ論理的だと思われます:

results, cursor, more = MyModel.query() \ 
    .order(-MyModel.time) \ 
    .fetch_page(20, start_cursor=Cursor(urlsafe=request.cursor)) 

そして...奇妙なことが起こります。決定的に多くの結果、順序付けられていない結果...何が起こっているのですか? だから私はそれを変更します。突然

results, cursor, more = MyModel.query(ancestor=mykey) \ 
    .order(-MyModel.time) \ 
    .fetch_page(20, start_cursor=Cursor(urlsafe=request.cursor)) 

、ワット以下の結果...さんは

.order(-MyModel.time) 

を追加してみましょうそして私は、私が期待したものを得ます。

今ここに何かがありますか?カーソルを渡すべきではありませんすでに注文と祖先の世話をする?ドキュメントの最初のページを取得するための注文例がある - https://cloud.google.com/appengine/docs/python/ndb/queries#cursors - しかし、それ以降のページでも順序を設定する必要はありません。私はそれが意図したとおりに実際に動作しているのか、それともバグか知りたいだけです。

実際に意図したとおりに動作している場合は、どこの情報がカーソルに正確に格納されているかについてはどこからでも知ることができますか?将来このようなバグを避けるのに本当に役立つでしょうか? Query Cursors

から

答えて

3

(MEからハイライト):

クエリカーソルは、クエリに 再開点を表す小さな不透明なデータ構造です。これは、一度にユーザーに ページの結果を表示するのに便利です。停止して再開する必要のある長いジョブ を処理する場合にも便利です。それらを使用する典型的な方法は、 クエリのfetch_page()メソッドです。これはfetch()のように動作しますが、 は結果(triple)(結果、カーソルなど)を返します。返されたmoreフラグ は、より多くの結果がある可能性があることを示します。 UIは の例でこれを使用して、「次のページ」ボタンまたはリンクを抑制することができます。 後続のページをリクエストするには、fetch_page()によって返されたカーソルを、 の次の呼び出しに渡します。

カーソルが生成された元のクエリのコンテキストでのみ存在し、意味をなさないため、1つのクエリ(あなたの場合は祖先クエリ)のコンテキストで生成されたカーソルは使用できません。別のクエリ(非祖先クエリ)からの結果をナビゲートします。私はそれがbarf(あなたの実験が証明するように)かもしれませんが、結果はおそらくあなたが期待しているものではないことを意味します:)

基本的に、カーソルはクエリの結果のリスト内の現在の位置(望むならインデックス)を表します。他のリストでそのインデックスを使用すると、クラッシュすることはありませんが、(特に設計されていない限り)多くの意味がありません。

おそらく、そのような偶発的な間違いを避けるために、毎回それを再構築するのではなく、再利用のためにクエリを格納するために変数を使用するのは良い習慣です。

# Set up. 
q = Bar.query() 
q_forward = q.order(Bar.key) 
q_reverse = q.order(-Bar.key) 

# Fetch a page going forward. 
bars, cursor, more = q_forward.fetch_page(10) 

# Fetch the same page going backward. 
r_bars, r_cursor, r_more = q_reverse.fetch_page(10, start_cursor=cursor) 

サイドノート:そのドキュメントにsnippets.py例に示すように、この例では、実際には別のクエリで検索結果をナビゲートするために、1つのクエリからカーソルを使用するが、2つのクエリは、「互換性」であるように設計されています。

+0

ありがとうございます。 問題はAPIを設計することです。オンラインストアのアイテムのリストを表示するアプリがあるとします。 GAEエンドポイントAPIを呼び出して、最初のN個のアイテムを読み込みます。ユーザーがリストの最後までスクロールすると、追加のページをロードしたい。 しかし、私のクエリオブジェクトはなくなりました!さらに、ユーザーがいくつかのフィルターを使用している可能性があります。私は私の要求にすべてのフィルタを追加し、元のものを作成してカーソルを追加する方法とまったく同じようにクエリ全体を再構築する必要があると思いますか? – mpiekarz

+0

はい、そのような場合は元のリクエストを再作成する必要があります。最初の例は、カーソル情報を「次へ」ボタンのURLにパラメータとして渡す方法を示していますが、エンドポイントでこれが可能かどうかはわかりません(エンドポイントではまだ遊んでいませんでした)。 –

関連する問題