查询存在的属性值集的数据存储

时间:2012-04-04 03:09:03

标签: google-app-engine properties google-cloud-datastore set

我有一个属性列,可以在任何时间点拥有以下值的子集:{ 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 peopleaddress { Iloilo | Laoag },然后我想要set(Iloilo, Laoag)

在进行任何查询之前,我不知道set应该构成什么。

我目前的方法要求我挖掘所有实体。这是非常低效的,还有更好的方法吗?

2 个答案:

答案 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将输出值和每个记录的出现次数。