Added tests, documentation and simplified code

This commit is contained in:
Matthieu Rigal
2015-06-21 03:03:50 +02:00
parent 2d57dc0565
commit 5efabdcea3
5 changed files with 70 additions and 32 deletions

View File

@@ -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))