2016-05-26 13 views
1

golangのデータストアクエリにいくつかの奇妙な問題があります。クエリーは正常に実行されますが、合計(cli.Count())を引き出す場合は、タイムアウトするたびに一貫して失敗します。私が何か間違っているのか、これを行う正しい方法があるのか​​誰かが説明できますか?奇妙な部分は、それがクエリの数に失敗し、私はなぜ、私はNewQueryを作成しようとしたと新しいクライアントを初期化しようとしたが、どちらも動作しないだけです。Golang Datastore任意の数を使用したクエリ

// GetListByID provides an iterative list of all items filtered by ID. 
func GetListByID(theID, limit, offset int) ([]Item, int, error) { 
    var itemList []Item 
    cli, ctx, err := getClient() 
    if err != nil { 
     return itemList, 0, err 
    } 
    if limit <= 0 { 
     limit = 20 
    } 

    q := datastore.NewQuery("SomeKind").Filter("MasterID = ", theID) 
    ql := q.Limit(limit).Offset(offset) 
    _, err = cli.GetAll(ctx, ql, &itemList) 
    if err != nil { 
     return itemList, 0, err 
    } 
    if len(itemList) < limit && offset == 0 { 
     return itemList, len(itemList), nil 
    } 
    total, err := cli.Count(ctx, q) 

    return itemList, total, err 
} 

appengineでは実行されませんのでご注意ください。 AWSとデータセンターのインスタンス上で動作します。 (尋ねないでください)

+0

正確なエラーメッセージは何ですか? –

答えて

0

答えは実際に私が期待していることですが、github(問題を提出しました)のOkDaveによって最近取り上げられたバグがありました。リンクはhttps://github.com/GoogleCloudPlatform/gcloud-golang/issues/268です。私は答えを更新するためにここに戻ることを忘れてappologizeし、私はあなたが実際に逃すかもしれない多くのことを説明するようにあなたの詳細を感謝します。私のニーズに対しては、実装されている機能性を損なうため、カーソルを使用したくありません。私は、選択されたアイテム50〜100の行に沿って何かが予想されています。クエリが再度実行されると、2番目のアイテム50〜100は、2番目のクエリの前に追加されたアイテムがデータベースに挿入されたものと同じであってはなりません。カーソルを使用する理由はありますが、私の場合はそうしたくない理由があります。私はそれを望んでいません。問題は固定された数にもっと関連していました。

1

注:Cloud Datastoreのサーバー側にはcountという集計はありません。これは、クライアントがcountのような関数をどのように実装するかを形作るときに知っておくことが重要です。

まず、あなたのコードはあなたが思っていることを行っていない可能性があります。

total, err := cli.Count(ctx, q)はすでに実行されたクエリからカウントを返していないため、クエリを取得してキーのみにしてから、すべてのキーを取得するために新しい呼び出しを発行しています。次に、必要に応じてカーソルを使用してページングし、すべての結果をカウントします。

あなたはimplementation here on gitHub

オフセット

オフセット見ることができます - (あなたが使用するように切り替える必要があります)カーソルとは異なり、オフセットは単にクエリが前回中断したところから再開することによって動作しません。オフセットを処理するには、Cloud Datastoreはクエリに一致するエンティティの数を手動でoffsetまでカウントしてから再開する必要があります。これは、関数のすべての呼び出しが、古典的なO(N^2)アルゴリズムである新しいものを処理する前に、すべての先行するエンティティを再処理していることを意味します。もう一度

:カーソルに切り替え:D

これは実際に、なぜあなたが取得しているタイムアウト(またはこの場合は、無限ループ)に関するものです。 Countの実装では、オフセット番号が保持されます。あなたが持っているエンティティの数や関数の呼び出し方法によっては、非常に大きくなる可能性があります。

これが最終的な答えに私たちをリード:あなたはこの質問が壊れていた書いたときに使用可能

カウント

囲碁クライアント。私はコミットの履歴を見て、それがオフセットを処理せず、最近まで正しく結果をスキップしていることに気づいただけです。これにより、Cloud Datastoreに進捗していない(オフセットの最初のエンティティをスキップしようとする)クエリが継続的に発行されるようになりました。カウント関数は、その後も継続してnextbatch()を呼び出して返されませんでした。

これは、コミット、次の経由月上旬修正されました:https://github.com/GoogleCloudPlatform/gcloud-golang/commit/0bf7a0795c591c70a17505c1123bc3ef3d30f426

あなたが行くクライアントの新しいバージョンを取得する場合は、任意のより多くのこの無限ループの問題を持つべきではありません。

関連する問題