如何在GAE上最佳设计日期/地域邻近查询?

1 投票
2 回答
886 浏览
提问于 2025-04-15 20:54

我正在用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

2 个回答

2

GeoModel 是我找到的最好的工具。你可以看看我的 GAE 应用 是如何处理地理空间查询的。例如,针对印度的 HTTP 查询可以使用可选的国家代码(cc),使用 geomodel 库的格式是 lat=20.2095231&lon=79.560344&cc=IN

1

你可能会对 geohash 感兴趣,它可以让你进行这样的不等式查询:

SELECT latitude, longitude, title FROM myMarkers WHERE geohash >= :sw_geohash AND geohash <= :ne_geohash

可以看看 这篇不错的文章,它在这个月的 Google App Engine 社区更新 博客中被推荐过。

关于你提到的设计,记得 Memcache 中的实体并不能保证一直保存在内存里,而且你不能按“日期”来排序它们。

撰写回答