[英]What is the equivalent of mongoengine.GeoPointField in motorengine to perform near queries?
I have the following model: class DbObjectWithCoordinates(Document): coordinates = GeoPointField() # this used to work with mongengine
我有以下模型:
class DbObjectWithCoordinates(Document): coordinates = GeoPointField() # this used to work with mongengine
I used the mongoengine.GeoPointField
to perform queries like find all objects near to given coordinates: 我使用
mongoengine.GeoPointField
执行查询,例如查找给定坐标附近的所有对象:
user_coordinates = user.coordinates
objects_of_interest = DbObjectWithCoordinates.objects(coordinates__near=user_coordinates, coordinaes_max_distance=3)
Howewer the GeoPointField
field is not available in motorengine. 然而,
GeoPointField
字段在发动机中不可用。 Is it possible to define objects and use queries like this with motorengine? 是否可以在Motorengine中定义对象并使用类似的查询? And if not is there a workaround for this kind of use case?
如果没有,这种用例是否有解决方法?
I think it would be fairly easy to implement geopoint field. 我认为实现geopoint字段将相当容易。 Below is very simple implementation offcourse it is not a full one.
下面是非常简单的实现途径,它不是一个完整的。
from motorengine.fields import *
from pymongo import GEOSPHERE, GEO2D
from motorengine.query.base import QueryOperator
from motorengine.utils import serialize, deserialize
class GeoPointField(BaseField):
def __init__(self, *args, **kwargs):
super(GeoPointField, self).__init__(*args, **kwargs)
def validate(self, lst):
if not isinstance(lst, (list, )):
return False
return True
def to_son(self, lst):
longitude = lst[1]
latitude = lst[0]
value = {"type": "Point", "coordinates": [latitude, longitude]}
return value
def from_son(self, jsn):
valued = jsn
longitude = valued.get("coordinates")[1]
latitude = valued.get("coordinates")[0]
return [latitude, longitude]
class GeoNearOperator(QueryOperator):
def to_query(self, field_name, value):
return {
field_name: {
"$near": {
"$geometry": {
"type": "Point",
"coordinates": list(value[0])
},
"$minDistance": value[1]
}
}
}
def get_value(self, field_name, raw_value):
return raw_value
class GeoSphearNearOperator(QueryOperator):
EARTH_RADIOUS = 3963.2
def to_query(self, field_name, value):
return {
field_name: {
"$geoWithin": {
"$centerSphere": [list(value[0]),
value[1]/self.EARTH_RADIOUS]
}
}
}
def get_value(self, field_name, raw_value):
return raw_value
class Events(MotorEngineDocument):
__indexes__ = [('location', GEOSPHERE)]
name = StringField(required=True)
tid = StringField(required=True)
event_on = DateTimeField(required=True)
location = GeoPointField(required=True)
@classmethod
async def nearby(cls, lat, lon, radious, limit=10, skip=0):
results = await cls.objects.limit(limit).skip(skip)\
.filter(location__around=[(lat, lon), radious])\
.find_all()
return results
But you need to be sure that the motorengine operators are updated properly before geo query. 但是,在地理查询之前,您需要确保正确更新了发动机操作员。
from motorengine.query_builder.transform import OPERATORS
OPERATORS.update({
"near": GeoNearOperator,
"around": GeoSphearNearOperator,
"search": TextSearch
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.