Added tests, documentation and simplified code
This commit is contained in:
@@ -6,7 +6,7 @@ from bson import SON
|
||||
from mongoengine.base.fields import UPDATE_OPERATORS
|
||||
from mongoengine.connection import get_connection
|
||||
from mongoengine.common import _import_class
|
||||
from mongoengine.errors import InvalidQueryError
|
||||
from mongoengine.errors import InvalidQueryError, LookUpError
|
||||
|
||||
__all__ = ('query', 'update')
|
||||
|
||||
@@ -44,8 +44,8 @@ def query(_doc_cls=None, _field_operation=False, **query):
|
||||
if len(parts) > 1 and parts[-1] in MATCH_OPERATORS:
|
||||
op = parts.pop()
|
||||
|
||||
# if user escape field name by __
|
||||
if len(parts) > 1 and parts[-1] == "":
|
||||
#if user escape field name by __
|
||||
if len(parts) > 1 and parts[-1]=="":
|
||||
parts.pop()
|
||||
|
||||
negate = False
|
||||
@@ -126,32 +126,28 @@ def query(_doc_cls=None, _field_operation=False, **query):
|
||||
elif key in mongo_query:
|
||||
if key in mongo_query and isinstance(mongo_query[key], dict):
|
||||
mongo_query[key].update(value)
|
||||
# $maxDistance needs to come last - convert to SON
|
||||
# $max/minDistance needs to come last - convert to SON
|
||||
value_dict = mongo_query[key]
|
||||
if ('$maxDistance' in value_dict and '$near' in value_dict):
|
||||
if ('$maxDistance' in value_dict or '$minDistance' in value_dict) and '$near' in value_dict:
|
||||
value_son = SON()
|
||||
if isinstance(value_dict['$near'], dict):
|
||||
for k, v in value_dict.iteritems():
|
||||
if k == '$maxDistance' or k == '$minDistance':
|
||||
continue
|
||||
value_son[k] = v
|
||||
if (get_connection().max_wire_version <= 1):
|
||||
value_son['$maxDistance'] = value_dict[
|
||||
'$maxDistance']
|
||||
else:
|
||||
value_son['$near'] = SON(value_son['$near'])
|
||||
for k, v in value_dict.iteritems():
|
||||
if k == '$maxDistance' or k == '$minDistance':
|
||||
continue
|
||||
value_son[k] = v
|
||||
if isinstance(value_dict['$near'], dict) and\
|
||||
get_connection().max_wire_version > 1:
|
||||
value_son['$near'] = SON(value_son['$near'])
|
||||
if '$maxDistance' in value_dict:
|
||||
value_son['$near'][
|
||||
'$maxDistance'] = value_dict['$maxDistance']
|
||||
if '$minDistance' in value_dict:
|
||||
value_son['$near'][
|
||||
'$minDistance'] = value_dict['$minDistance']
|
||||
else:
|
||||
for k, v in value_dict.iteritems():
|
||||
if k == '$maxDistance' or k == '$minDistance':
|
||||
continue
|
||||
value_son[k] = v
|
||||
if '$maxDistance' in value_dict:
|
||||
value_son['$maxDistance'] = value_dict['$maxDistance']
|
||||
if '$minDistance' in value_dict:
|
||||
value_son['$minDistance'] = value_dict['$minDistance']
|
||||
|
||||
mongo_query[key] = value_son
|
||||
else:
|
||||
# Store for manually merging later
|
||||
@@ -305,7 +301,11 @@ def update(_doc_cls=None, **update):
|
||||
|
||||
def _geo_operator(field, op, value):
|
||||
"""Helper to return the query for a given geo query"""
|
||||
if field._geo_index == pymongo.GEO2D:
|
||||
if op == "max_distance":
|
||||
value = {'$maxDistance': value}
|
||||
elif op == "min_distance":
|
||||
value = {'$minDistance': value}
|
||||
elif field._geo_index == pymongo.GEO2D:
|
||||
if op == "within_distance":
|
||||
value = {'$within': {'$center': value}}
|
||||
elif op == "within_spherical_distance":
|
||||
@@ -318,10 +318,6 @@ def _geo_operator(field, op, value):
|
||||
value = {'$nearSphere': value}
|
||||
elif op == 'within_box':
|
||||
value = {'$within': {'$box': value}}
|
||||
elif op == "max_distance":
|
||||
value = {'$maxDistance': value}
|
||||
elif op == "min_distance":
|
||||
value = {'$minDistance': value}
|
||||
else:
|
||||
raise NotImplementedError("Geo method '%s' has not "
|
||||
"been implemented for a GeoPointField" % op)
|
||||
@@ -340,10 +336,6 @@ def _geo_operator(field, op, value):
|
||||
value = {"$geoIntersects": _infer_geometry(value)}
|
||||
elif op == "near":
|
||||
value = {'$near': _infer_geometry(value)}
|
||||
elif op == "max_distance":
|
||||
value = {'$maxDistance': value}
|
||||
elif op == "min_distance":
|
||||
value = {'$minDistance': value}
|
||||
else:
|
||||
raise NotImplementedError("Geo method '%s' has not "
|
||||
"been implemented for a %s " % (op, field._name))
|
||||
|
||||
Reference in New Issue
Block a user