Python 谷歌应用程序引擎的排序问题
我使用以下类存储一些数据:Python 谷歌应用程序引擎的排序问题,python,google-app-engine,google-cloud-datastore,Python,Google App Engine,Google Cloud Datastore,我使用以下类存储一些数据: class NewsArticle(db.Model): score = db.FloatProperty(default=0.0) date_scored = db.DateTimeProperty() ... 我需要做的是获取在某个时间范围内得分最高的新闻文章实体(例如获取今天或上周得分最高的数据实体) 我尝试了以下方法: query = db.GqlQuery('SELECT * FROM NewsArticle WHERE date_
class NewsArticle(db.Model):
score = db.FloatProperty(default=0.0)
date_scored = db.DateTimeProperty()
...
我需要做的是获取在某个时间范围内得分最高的新闻文章实体(例如获取今天或上周得分最高的数据实体)
我尝试了以下方法:
query = db.GqlQuery('SELECT * FROM NewsArticle WHERE date_created > DATETIME(:year, :month, :day, 0, 0, 0) ORDER BY score DESC', year=date.selected_year, month=date.selected_month, day=date.selected_day)
但这不起作用,因为数据存储要求
第一个排序属性必须是
与不等式过滤器属性相同
我曾考虑过获取特定时间段内的所有新闻文章实体,然后在我的应用程序中进行分数排序,但我希望得到大量结果,因此内存排序将不会有效
对于我的问题,还有哪些其他解决方案?试试以下方法:
import datetime
...
query = Data.gql('SELECT * FROM NewsArticle WHERE date_created >= :today ORDER BY score DESC', today=datetime.date.today())
试试这个:
import datetime
...
query = Data.gql('SELECT * FROM NewsArticle WHERE date_created >= :today ORDER BY score DESC', today=datetime.date.today())
你可以:
编辑:要了解更多信息,请查看我认为按多个属性排序可能会奏效。只需使用第一个不等式属性作为第一个排序属性
query = db.GqlQuery('SELECT * FROM NewsArticle WHERE date_created > DATETIME(:year, :month, :day, 0, 0, 0) ORDER BY date_created, score DESC', year=date.selected_year, month=date.selected_month, day=date.selected_day)
我认为按多个属性排序可能有效。只需使用第一个不等式属性作为第一个排序属性
query = db.GqlQuery('SELECT * FROM NewsArticle WHERE date_created > DATETIME(:year, :month, :day, 0, 0, 0) ORDER BY date_created, score DESC', year=date.selected_year, month=date.selected_month, day=date.selected_day)
我期待着一个非常大的数字
这样内存中的排序就不会
要有效率
你可以从查询中得到最多1000个结果,所以按每种方式排序它们都是<强>极<强/ >高效-例如,在我的MacBook Air(第一天,最慢的模型)上考虑:
AppEngine的CPU速度远远快于Air,因此700微秒对1000个结果进行排序将是一个非常悲观的估计;这与获取数据的几十毫秒相比——因此,根本不必担心排序问题:只要能够获取所需的结果,就可以了 顺便说一句,要评估应用程序引擎在任务中可能的性能,请参见Guido van Rossum的演示——他声称“典型的db.get()
”(50-100表示put
,等等)
如果一个查询的结果超过1000个,这通常意味着您需要对表进行反规范化,以将查询的结果修剪到1000个以下。例如,在您的例子中,假设您预计每天大约有500-700个条目——在这种情况下,获取今天的所有结果是没有问题的,但一周肯定是个问题:您需要将查询减少到“正常”情况下的20%或更少
例如,假设你的分数在0-100之间,大约均匀分布。在这种情况下,您可以向实体添加一个布尔字段“topcandidate”:当您保存实体时,如果分数在85-100范围内,则将该字段设置为True(如您所见,这意味着该表将被非规范化,因为该字段表示逻辑冗余信息)
获取每周top结果时,添加相等条件以使TOPCANDABLE为True。而不是3500-4900个结果,这将使你下降到500-900个——得分最高的15%左右,之后你可以在内存中对它们进行排序,然后选择,比如说,前100个
当然,确切的数字取决于分数
字段的分布(更可能是钟形曲线,而不是平坦的均匀分布)以及您需要多少“最高分数候选人”,但这是一种通常有用的方法,可以绕过1000个结果限制
我期待着一个非常大的数字
这样内存中的排序就不会
要有效率
你可以从查询中得到最多1000个结果,所以按每种方式排序它们都是<强>极<强/ >高效-例如,在我的MacBook Air(第一天,最慢的模型)上考虑:
AppEngine的CPU速度远远快于Air,因此700微秒对1000个结果进行排序将是一个非常悲观的估计;这与获取数据的几十毫秒相比——因此,根本不必担心排序问题:只要能够获取所需的结果,就可以了 顺便说一句,要评估应用程序引擎在任务中可能的性能,请参见Guido van Rossum的演示——他声称“典型的db.get()
”(50-100表示put
,等等)
如果一个查询的结果超过1000个,这通常意味着您需要对表进行反规范化,以将查询的结果修剪到1000个以下。例如,在您的例子中,假设您预计每天大约有500-700个条目——在这种情况下,获取今天的所有结果是没有问题的,但一周肯定是个问题:您需要将查询减少到“正常”情况下的20%或更少
例如,假设你的分数在0-100之间,大约均匀分布。在这种情况下,您可以向实体添加一个布尔字段“topcandidate”:当您保存实体时,如果分数在85-100范围内,则将该字段设置为True(如您所见,这意味着该表将被非规范化,因为该字段表示逻辑冗余信息)
获取每周top结果时,添加相等条件以使TOPCANDABLE为True。而不是3500-4900个结果,这将使你下降到500-900个——得分最高的15%左右,之后你可以在内存中对它们进行排序,然后选择,比如说,前100个
当然,确切的数字取决于分数字段的分布(更可能是钟形曲线)