Merge branch 'geo' of git://github.com/blackbrrr/mongoengine into v0.4

Conflicts:
	mongoengine/fields.py
	mongoengine/queryset.py
This commit is contained in:
Harry Marr
2010-07-07 14:53:25 +01:00
4 changed files with 119 additions and 30 deletions

View File

@@ -241,21 +241,22 @@ class QuerySet(object):
# Ensure document-defined indexes are created
if self._document._meta['indexes']:
for key_or_list in self._document._meta['indexes']:
#self.ensure_index(key_or_list)
self._collection.ensure_index(key_or_list)
# Ensure indexes created by uniqueness constraints
for index in self._document._meta['unique_indexes']:
self._collection.ensure_index(index, unique=True)
# If _types is being used (for polymorphism), it needs an index
if '_types' in self._query:
self._collection.ensure_index('_types')
# Ensure all needed field indexes are created
for field_name, field_instance in self._document._fields.iteritems():
if field_instance.__class__.__name__ == 'GeoLocationField':
self._collection.ensure_index([(field_name, pymongo.GEO2D),])
for field in self._document._fields.values():
if field.__class__._geo_index:
index_spec = [(field.db_field, pymongo.GEO2D)]
self._collection.ensure_index(index_spec)
return self._collection_obj
@property
@@ -311,9 +312,10 @@ class QuerySet(object):
"""Transform a query from Django-style format to Mongo format.
"""
operators = ['ne', 'gt', 'gte', 'lt', 'lte', 'in', 'nin', 'mod',
'all', 'size', 'exists', 'near']
match_operators = ['contains', 'icontains', 'startswith',
'istartswith', 'endswith', 'iendswith',
'all', 'size', 'exists']
geo_operators = ['within_distance', 'within_box', 'near']
match_operators = ['contains', 'icontains', 'startswith',
'istartswith', 'endswith', 'iendswith',
'exact', 'iexact']
mongo_query = {}
@@ -321,7 +323,7 @@ class QuerySet(object):
parts = key.split('__')
# Check for an operator and transform to mongo-style if there is
op = None
if parts[-1] in operators + match_operators:
if parts[-1] in operators + match_operators + geo_operators:
op = parts.pop()
if _doc_cls:
@@ -335,15 +337,25 @@ class QuerySet(object):
singular_ops += match_operators
if op in singular_ops:
value = field.prepare_query_value(op, value)
elif op in ('in', 'nin', 'all'):
elif op in ('in', 'nin', 'all', 'near'):
# 'in', 'nin' and 'all' require a list of values
value = [field.prepare_query_value(op, v) for v in value]
if field.__class__.__name__ == 'GenericReferenceField':
parts.append('_ref')
if op and op not in match_operators:
value = {'$' + op: value}
# if op and op not in match_operators:
if op:
if op in geo_operators:
if op == "within_distance":
value = {'$within': {'$center': value}}
elif op == "near":
value = {'$near': value}
else:
raise NotImplementedError("Geo method '%s' has not "
"been implemented" % op)
elif op not in match_operators:
value = {'$' + op: value}
key = '.'.join(parts)
if op is None or key not in mongo_query: