如何获取Google App Engine中我的模型的不同值
我有一个模型,下面的内容是关于如何获取所有不同的 area
值。就像在SQL中可以用 select distinct area from tutorials
来实现一样。
class Tutorials(db.Model):
path = db.StringProperty()
area = db.StringProperty()
sub_area = db.StringProperty()
title = db.StringProperty()
content = db.BlobProperty()
rating = db.RatingProperty()
publishedDate = db.DateTimeProperty()
published = db.BooleanProperty()
我知道在Python中我可以这样做:
a = ['google.com', 'livejournal.com', 'livejournal.com', 'google.com', 'stackoverflow.com']
b = set(a)
b
>>> set(['livejournal.com', 'google.com', 'stackoverflow.com'])
但是这样做的话,我需要把area的项目从查询中提取出来,放到另一个列表里,然后再对这个列表进行去重(听起来效率很低)。而且如果我的数据存储中有一个不同的项目在第1001个位置,我就看不到它,因为取出的限制是1000。
我想要获取我数据存储中所有不同的area值,然后把它们作为链接显示在屏幕上。
3 个回答
这个问题之前有人问过,大家得出的结论是使用集合(sets)是可以的。
DISTINCT这个关键词是在1.7.4版本中引入的。
数据存储系统不能通过一次查询来完成你想要的事情。每次请求数据存储时,系统总是会从一个索引中返回一块连续的结果,而这个索引包含了所有特定类型的实体,并按照你指定的顺序进行排序。查询无法跳过某些项目,仅仅因为某个字段有重复的值。
一个解决方案是重新组织你的数据。比如,可以引入一个新的实体类型来表示“区域”。在添加一个教程时,如果对应的“区域”还不存在,就创建一个;在删除一个教程时,如果没有其他教程与这个“区域”相关联,就删除这个“区域”。如果每个区域都存储了该区域内教程的数量,这样做可能不会太麻烦(不过保持数据一致性,比如事务处理等,确实会比较复杂)。我猜这个实体的键可以基于区域的字符串,这样你就可以通过键查找,而不是查询来获取区域实体。
另一个选择是使用排队任务或定时任务,定期创建一个所有区域的列表,如果需要,可以在多次请求中累积这些数据,并将结果存储在数据存储中或内存缓存中。当然,这样做意味着区域列表有时可能会暂时过时(或者如果变化频繁,可能永远不会完全更新),这可能对你来说是可以接受的,也可能不可接受。
最后,如果区域的数量相对于教程来说非常少,你可以实时处理。比如先请求第一个教程(按区域排序),然后请求下一个区域大于第一个区域的第一个教程,依此类推。但这样每个不同的区域都需要一次请求,所以速度可能不会很快。