0

我有一个属性列,它可以在任何时间点包含以下值的子集:{ 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,000people人都有一个addressof { Manila | Cebu | Davao },那么我想要set(Manila, Cebu, Davao).

在另一个时间点,所有 5,000,000people都会有一个addressof { Iloilo | Laoag },那么我想要set(Iloilo, Laoag).

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

我目前的方法要求我挖掘所有实体。效率太低了,有什么更好的方法吗?

4

2 回答 2

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 次写入/秒的速度增加一个以上的人,那么您可能还需要考虑对城市列表进行分片。

于 2012-04-04T07:04:48.157 回答
1

Albert 建议的方法的替代方法是使用 mapreduce 定期计算这些值。App Engine Mapreduce库使这变得相当简单。您的映射器将输出每条记录的城市(例如),而化简器将输出每条记录的值和出现的次数。

于 2012-04-05T06:03:56.893 回答