如何在GAE上最佳设计日期/地域邻近查询?
我正在用web2py和Flex前端在GAE上建立一个查找体育比赛的目录。用户可以选择一个地点、一个半径和一个最大日期。我已经实现了这个查询的基本版本,但它效率低下,速度慢。我知道可以通过把很多单独的查询合并成批量查询来改善这个问题。我刚刚了解到这是可能的。不过,我也在考虑一个更全面的重新设计,利用memcache。
主要的问题是,我无法通过地点查询数据存储,因为GAE不允许在一个查询中使用多个数字比较语句(比如小于、小于等于、大于等于)。我已经在用一个比较日期,而我需要两个来检查纬度和经度,所以这行不通。目前,我的算法大致是这样的:
1.) 按日期查询并选择
2.) 使用geopy的距离模块中的目标函数来找到给定距离的最大和最小纬度和经度
3.) 遍历结果,去掉所有纬度/经度超出最大/最小范围的结果
4.) 再次遍历,使用距离函数检查确切距离,因为第2步会包含一些超出半径的区域。去掉超出给定距离的结果(这2/3/4的组合效率低吗?)
5.) 组装多对多的列表并附加到对象上(这就是我需要切换到批量操作的地方)
6.) 返回给客户端
这是我使用memcache的计划……如果我想得太远了,请告诉我,因为我之前没有使用过memcache或服务器缓存。
- 在缓存中保持一个列表,里面装着代表我所有数据的“地理对象”。这些对象有五个属性:纬度、经度、事件ID、事件类型(为了将来扩展到比赛以外的活动),和开始日期。这个列表会按日期排序。
- 还要在缓存中保持一个指针字典,表示我的应用使用的所有日期范围的开始和结束索引(下周、两周、一个月、三个月、六个月、一年、两年)。
- 设置一个定时任务,每天凌晨12点更新指针。
- 将新插入的数据同时添加到缓存和数据存储中;更新指针。
使用这个设计,算法现在看起来会是:
1.) 使用指针根据给定日期切割出合适的列表部分。
2-4.) 和上面的算法一样,只不过是用地理对象。
5.) 使用批量操作选择完整的比赛,使用剩余地理对象的事件ID。
6.) 组装多对多的关系。
7.) 返回给客户端。
对这个方法有什么看法?非常感谢你的阅读和任何建议。
-Dane