我在3个月前开始使用Google App Engine,我对memcaching上的Python有疑问。 我试着尽可能地描述我的问题。
我使用ndb (App Engine Datastore)并且我有一个"表"像这样的实体:
class Event(ndb.Model):
dateInsert = ndb.DateTimeProperty(auto_now_add=True) # Inserting date
notes = ndb.StringProperty(indexed=False) # event notes
geohash = ndb.StringProperty(required=True) # Coordinates geohash
eventLatitude = ndb.FloatProperty(indexed=True, required=True) # self explanatory
eventLongitude = ndb.FloatProperty(indexed=True, required=True) # self explanatory
客户端(例如,使用移动应用程序)用户可以在数据存储区中存储指定坐标中的事件。 那些插入的事件当然可以通过移动应用程序(在地图上)和网站上看到。 现在要检索存储的事件,客户端调用一个web方法来搜索给定位置附近的事件:
class getEvents(webapp.RequestHandler):
def get(self):
#blablabla get passed parameters
#[...]
# hMinPos and hMaxPos are hashed coordinates passed by client + X meters.
# In this way I can filter stored events in a precise bounding box.
# For example, I can get events near my location in a box of 5000 meters
qryEvent = Event.query(ndb.AND(Event.geohash >= hMinPos, Event.geohash <= hMaxPos))
events = qryEvent.fetch(1000)
然后我必须以循环周期获取每个结果以创建一个JSON来存储在列表中并将其返回给客户端。 所以它是
for event in events:
#do my stuff
一切都运行正常,但是大问题是无用的读取操作每次我称之为该方法。
我的意思是,每次调用方法时,它都会获取与其他客户端请求相同的事件,或者比同一客户端的先前请求更糟,相同的事件(如果我移动50米并且我发出客户端请求,事件与之前的请求相同ad 99% )。
这将很快占用配额和读取操作超额配额。
我想我应该使用memcache
来存储已获取的事件,并在从数据存储区读取之前在memcache中读取它们,但我不知道用我的结构来实现它。
我的想法是使用geohash作为memcache密钥,但是我不能遍历缓存的元素,我只能对给定的密钥进行精确获取,因此我的解决方案不适用(我无法解决)使用密钥直接访问memcache,我需要在memcache元素中迭代以找到适合我的坐标范围请求的事件。 有人有提示或建议吗?
答案 0 :(得分:1)
我可以想到2个解决方案:
1)在memcached中存储具有纬度 - 经度标识符的较小框(例如100米长)的信息。您可以从ndb请求一个大的例如5500米长,并保存memcached中所有包含的小方框的信息。当用户移动50米,100米或400米时,您将能够使用memcached数据向她提供答案,如果有人靠近该地点(500米内),则会发生同样的事情。
2)您可以使用ElasticSearch,特别是Geo Distance Filter。有了它,您可以过滤"documents that include only hits that exists within a specific distance from a geo point"
。
注意:如果 getEvents 在5000米的方框中返回事件,那么移动50米但距离较远时,您不应该触发新请求。