如何获取Google App Engine中我的模型的不同值

5 投票
3 回答
2624 浏览
提问于 2025-04-15 13:09

我有一个模型,下面的内容是关于如何获取所有不同的 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 个回答

0

这个问题之前有人问过,大家得出的结论是使用集合(sets)是可以的。

1

DISTINCT这个关键词是在1.7.4版本中引入的。

7

数据存储系统不能通过一次查询来完成你想要的事情。每次请求数据存储时,系统总是会从一个索引中返回一块连续的结果,而这个索引包含了所有特定类型的实体,并按照你指定的顺序进行排序。查询无法跳过某些项目,仅仅因为某个字段有重复的值。

一个解决方案是重新组织你的数据。比如,可以引入一个新的实体类型来表示“区域”。在添加一个教程时,如果对应的“区域”还不存在,就创建一个;在删除一个教程时,如果没有其他教程与这个“区域”相关联,就删除这个“区域”。如果每个区域都存储了该区域内教程的数量,这样做可能不会太麻烦(不过保持数据一致性,比如事务处理等,确实会比较复杂)。我猜这个实体的键可以基于区域的字符串,这样你就可以通过键查找,而不是查询来获取区域实体。

另一个选择是使用排队任务或定时任务,定期创建一个所有区域的列表,如果需要,可以在多次请求中累积这些数据,并将结果存储在数据存储中或内存缓存中。当然,这样做意味着区域列表有时可能会暂时过时(或者如果变化频繁,可能永远不会完全更新),这可能对你来说是可以接受的,也可能不可接受。

最后,如果区域的数量相对于教程来说非常少,你可以实时处理。比如先请求第一个教程(按区域排序),然后请求下一个区域大于第一个区域的第一个教程,依此类推。但这样每个不同的区域都需要一次请求,所以速度可能不会很快。

撰写回答