我有一个属性列,可以在任何时间点拥有以下值的子集:{ a | b | c | d | e }
。我的意思是,有时它可以是{ a | d | e }
中的任何一个,或者在其他时间它甚至可以是{ x | y | z }
。如何查询数据存储区,以便我可以找出该时间点存在的子集,而无需深入研究每个实体?
目前我这样做:
people = Person.all().fetch(100)
city = set()
for p in people:
city.add(p.address)
我想获得此时存在的属性值集(即没有重复项)。例如,在某个时间点,所有5,000,000 people
都有address
{ Manila | Cebu | Davao }
,那么我想要set(Manila, Cebu, Davao)
。
在另一个时间点,所有5,000,000 people
将address
{ Iloilo | Laoag }
,然后我想要set(Iloilo, Laoag)
。
在进行任何查询之前,我不知道set
应该构成什么。
我目前的方法要求我挖掘所有实体。这是非常低效的,还有更好的方法吗?
答案 0 :(得分:2)
在AppEngine中,在写入时间内生成和存储您可能需要的东西几乎总是更好。
因此,在您的使用案例中,每次添加或编辑人员实体时,都会将他们所在的城市添加到列出所有城市的另一个模型中,然后同时存储这些城市实体。
class Cities(db.Model):
list_of_cities = db.TextProperty(default="[]") #we'll use a stringified json list of cities
#when creating a new person / or when editing
person = Person(city = city)
cities = Cities.all().get() #there's only one model that we'll use.
list_of_cities = simplejson.loads(cities.list_of_cities)
if city not in list_of_cities:
list_of_cities.append(city) #add to the list of cities
cities.list_of_cities = simplejson.dumps(list_of_cities)
db.put(cities)
person.put()
您可能希望在城市实体上使用memcache来加快速度。如果您还希望以超过1次写入/秒的突发添加多个人,那么您可能还需要考虑对城市列表进行分片。
答案 1 :(得分:1)
Albert提出的方法的替代方案是使用mapreduce定期计算这些值。 App Engine Mapreduce库使这相当简单。您的映射器将为每个记录输出城市(例如),而reducer将输出值和每个记录的出现次数。