メニュー

2010年8月11日

Google App EngineでListPropertyを使おう

ListPropertyは複数の値が格納できる、便利なプロパティです。

複合インデックスでのインデックス爆発という問題はありますが、ListPropertyはGoogle App Engineには欠かせません。

複数選択が可能な(formでチェックボックスになるもの)は、ListPropertyを使うと実装しやすいです。

例えば、好きな動物というデータがあったとして:

class User(db.Model):
  fav = db.StringListProperty()

user = User()
user.fav = ['cat', 'dog', 'penguin']

としておけば、

users = User.all().filter('fav =', 'penguin')

のように、ペンギンが好きなユーザをクエリできます。

ここで問題なのは「どの動物も好きではない」ユーザをクエリで検索できないことです。
GQLではListPropertyが空であるという条件を表現できません。

そこで、ListPropertyのサイズも保存しておきます。

class User(db.Model):
  fav = db.StringListProperty()
  fav_len = db.IntegerProperty()

user = User()
user.fav = ['cat', 'dog', 'penguin']
user.fav_len = len(user.fav)

こうしておくと、fav_lenに要素数が入ります。
「どの動物も好きではない」ユーザは要素数がゼロですので、

users = User.all().filter('fav_len =', 0)

としてクエリで取得することが出来るようになります。

なお、他のプロパティと連動するプロパティにはComputedPropertyが便利です。
上記のUserを書き換えると:

class User(db.Model):
  fav = db.StringListProperty()
  @db.ComputedProperty
  def fav_len(self):
    return len(self.fav)

となります。これでエンティティが保存されるときに、自動でfav_lenがセットされます。