在app引擎(ndb或db)中处理计数的适当方法是什么?
我有两个项目是django-nonrel,另一个是纯django项目,但都需要能够进行查询并获得倒计时。结果可能大于1,000。
我看到一些帖子说我可以使用Sharded Counters,但他们正在计算所有实体。我需要知道有多少实体具有以下属性x = 1,y = True,z = 3
#Is this the appropriate way?
count = some_entity.gql(query_string).count(SOME_LARGE_NUMBER)
答案 0 :(得分:5)
数据存储区并不擅长此类查询,因为要进行权衡以使其分布。这些包括相当慢的读取和非常有限的索引。
如果您需要一组有限的统计信息(用户数,文章数等),那么您可以在一个单独的实体中继续运行总计。这意味着当需要更改时,您需要执行两次写入(puts):一次用于更改的实体,另一次用于更新stats实体。但是你只需要一个读取(get)来获取统计数据,而不是从中提炼出很多实体。
你可能对此感到不舒服,因为它违背了我们所知道的关于规范化的内容,但它效率更高,并且在许多情况下工作正常。如果这是至关重要的,您可以随时定期执行cron作业以查看统计信息是否准确。
答案 1 :(得分:3)
由于您使用db.Model,这里有一种方法可以计算您的所有实体,其中一些过滤器可能超过1000,这是一个硬限制(如果它仍然适用):
FETCH_LIMIT = 1000
def count_model(x=1, y=True, z=3):
model_qry = MyModel.all(keys_only=True)
model_qry.filter('x =', x)
model_qry.filter('y =', y)
model_qry.filter('z =', z)
count = None
total = 0
cursor = None
while count != 0:
if cursor:
count = model_qry.with_cursor(cursor).count()
else:
count = model_qry.count(limit=FETCH_LIMIT)
total += count
cursor = model_qry.cursor()
return total
如果您要在请求中使用上述内容,则可能会超时,因此请考虑使用Task Queues。
同样如FoxyLad所建议的那样,出于性能原因将上述方法作为一个cron作业定期运行以使统计数据处于完美同步状态,最好在一个单独的实体中保持运行总数。