データストアに保存したデータが1000件を超えた場合の対処方法は?

317 views
Skip to first unread message

Tomoaki Oshima

unread,
Jan 22, 2009, 6:43:41 PM1/22/09
to Google-App-Engine-Japan
DataStoreにdb.Modelを継承したクラスを使ってどんどんデータを蓄積していった場合で、
1000件を超えた場合、
GqlQueryの fetch() メソッドの 1000 まで制限のため、
1000件以降のデータが取り出せなくなるのですが、どうすればいいのでしょうか。

たとえば、10件ごと順番に取り出していく・・・という方法(API)が提供されていると
思っていたのですが、わたしが調べた範囲では、わからなかったので、
ここで質問させていただきました。

もし、逐次取り出しAPIがない場合は、
1000件制限を回避するためのアイデアをお持ちの方、教えてください。

ちなみに、わたしは以下のようにモデルに前のモデルへのid を持たせることで、
数珠繋ぎに取り出せるようにして問題を回避しようとしていますが、
もっとスマートな方法があるはずです・・・

class MyModel(db.Model):
id = db.StringProperty()
prev_id = db.StringProperty()
body = db.TextProperty()


■参考リンク
- http://code.google.com/intl/ja/appengine/docs/python/datastore/gqlqueryclass.html
> fetch() returns a maximum of 1000 results.

大島

kimio tanaka

unread,
Jan 22, 2009, 8:15:42 PM1/22/09
to google-app-...@googlegroups.com
> GqlQueryの fetch() メソッドの 1000 まで制限

はじめて 1000件制限に気がついたときは、
安易な対策ですが、
model に "年月" のような新しい Property を追加して対
応することで、必ず検索結果が 1000件以内に収まるように
しました。

それで、この追加した Property の値を埋めていくために
where 年月 = None  の条件で検索してみて、
後から追加した Property には " = None " による検索が
できないことにも気がつき、驚くとともに少し仕組みがわかって
きたような気もしました。
http://webdba.blogspot.com/2008/06/none.html

そして、次からは 1000件以上になるようものには
"年月" のような Property の設定と同時に、
試しにParent を設定するようにしてみましたが、あまり
この Parent には意味がなく....

> 数珠繋ぎに取り出せるようにして問題を回避しようとしていますが、
こういうアイデアもあるのですね。

田中


2009/01/23 8:43 Tomoaki Oshima <bl...@osima.jp>:

Tomoaki Oshima

unread,
Jan 23, 2009, 5:42:39 AM1/23/09
to Google-App-Engine-Japan
田中さま

グッドアイデアをありがとうございます。
なるほど年月を入れるとは思いつきませんでした。
取り急ぎお礼まで。

大島

On 1月23日, 午前10:15, kimio tanaka <kwin...@gmail.com> wrote:
> > GqlQueryの fetch() メソッドの 1000 まで制限
>
> はじめて 1000件制限に気がついたときは、
> 安易な対策ですが、
> model に "年月" のような新しい Property を追加して対
> 応することで、必ず検索結果が 1000件以内に収まるように
> しました。
>
> それで、この追加した Property の値を埋めていくために
> where 年月 = None  の条件で検索してみて、
> 後から追加した Property には " = None " による検索が
> できないことにも気がつき、驚くとともに少し仕組みがわかって
> きたような気もしました。http://webdba.blogspot.com/2008/06/none.html
>
> そして、次からは 1000件以上になるようものには
> "年月" のような Property の設定と同時に、
> 試しにParent を設定するようにしてみましたが、あまり
> この Parent には意味がなく....
>
> > 数珠繋ぎに取り出せるようにして問題を回避しようとしていますが、
>
> こういうアイデアもあるのですね。
>
> 田中
>
> 2009/01/23 8:43 Tomoaki Oshima <b...@osima.jp>:
>
>
>
> > DataStoreにdb.Modelを継承したクラスを使ってどんどんデータを蓄積していった場合で、
> > 1000件を超えた場合、
> > GqlQueryの fetch() メソッドの 1000 まで制限のため、
> > 1000件以降のデータが取り出せなくなるのですが、どうすればいいのでしょうか。
>
> > たとえば、10件ごと順番に取り出していく・・・という方法(API)が提供されていると
> > 思っていたのですが、わたしが調べた範囲では、わからなかったので、
> > ここで質問させていただきました。
>
> > もし、逐次取り出しAPIがない場合は、
> > 1000件制限を回避するためのアイデアをお持ちの方、教えてください。
>
> > ちなみに、わたしは以下のようにモデルに前のモデルへのid を持たせることで、
> > 数珠繋ぎに取り出せるようにして問題を回避しようとしていますが、
> > もっとスマートな方法があるはずです・・・
>
> > class MyModel(db.Model):
> > id = db.StringProperty()
> > prev_id = db.StringProperty()
> > body = db.TextProperty()
>
> > ■参考リンク
> > -http://code.google.com/intl/ja/appengine/docs/python/datastore/gqlque...

Kitahara

unread,
Jan 23, 2009, 11:24:57 PM1/23/09
to Google-App-Engine-Japan
keyの順番にならんでるのであれば、以下のドキュメントの実装で、逐次取り出せますよ。

http://code.google.com/intl/en/appengine/docs/python/datastore/queriesandindexes.html#Queries_on_Keys

new_last_key_str = str(entities[19].key())

でっ

http://...?last=new_last_key_str

とするのがポイントです。

私はこれをkey.().id()でやってます。

北原

kimio tanaka

unread,
Jan 24, 2009, 6:49:54 AM1/24/09
to google-app-...@googlegroups.com
>http://code.google.com/intl/en/appengine/docs/python/datastore/queriesandindexes.html#Queries_on_Keys

これはみのがしてしまっていました。
ちなみに、他の検索条件を追加してみたところ

db.GqlQuery('SELECT * FROM Blog
where __key__ > :1 and url2 = :2 ORDER BY __key__ limit 30',
last_key,url2 );

以下の index の追加が必要でしたが、

- kind: Blog
properties:
- name: url2
- name: __key__

問題なく動作しました。
" Unlike offset, this works efficiently for any number of entities "
まさに offset と違って件数が増えていっても、これは快適に動作しますね。
とても参考になり、ありがとうございました。

田中


2009/01/24 13:24 Kitahara <surg...@gmail.com>:

Tomoaki Oshima

unread,
Jan 25, 2009, 1:01:03 PM1/25/09
to Google-App-Engine-Japan
北原 さま
ありがとうございます!助かりました・・・
紹介いただいたページの通りでOKでした。

#last_key=aMyModel.key().id() #NG
last_key=aMyModel.key()
query = MyModel.gql('WHERE __key__ >= :1 ORDER BY __key__ ',
last_key)


それから、
以下のGQL クエリでは limit が無効になるようです。(実際のGAE上で)

query=MyModel.gql('ORDER BY __key__ limit 20')
count=query.count() # 20 にはならないで、実際にストアされているMyModelの数になる

軽くテストしただけなので、単なる勘違いかもしれません。

GAEでは、一度のリクエストで使えるリソースが結構少ないので、
MyModelが大量にあった場合に、limit なしで gql クエリを発行するとリソースを使い切って
エラーになる可能性が高いので、limit指定が効かないとちょっと心配です。

ちなみに、GAE管理画面のDataVierwerでは、以下のようなlimit つきクエリが意図どおり作動しました。

SELECT * FROM MyModel ORDER BY __key__ limit 1


以上、取り急ぎお礼と報告まで

大島(http://osima.jp/)


On 1月24日, 午後1:24, Kitahara <surgo...@gmail.com> wrote:
> keyの順番にならんでるのであれば、以下のドキュメントの実装で、逐次取り出せますよ。
>
> http://code.google.com/intl/en/appengine/docs/python/datastore/querie...
Reply all
Reply to author
Forward
0 new messages