Updated index creation now tied to Document class ((MongoEngine/mongoengine#102)
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import pprint
|
||||
import re
|
||||
import copy
|
||||
import itertools
|
||||
import operator
|
||||
import pprint
|
||||
import re
|
||||
import warnings
|
||||
|
||||
import pymongo
|
||||
from bson.code import Code
|
||||
import pymongo
|
||||
from pymongo.common import validate_read_preference
|
||||
|
||||
from mongoengine import signals
|
||||
@@ -37,8 +38,6 @@ class QuerySet(object):
|
||||
"""A set of results returned from a query. Wraps a MongoDB cursor,
|
||||
providing :class:`~mongoengine.Document` objects as the results.
|
||||
"""
|
||||
|
||||
__already_indexed = set()
|
||||
__dereference = False
|
||||
|
||||
def __init__(self, document, collection):
|
||||
@@ -95,24 +94,6 @@ class QuerySet(object):
|
||||
self._mongo_query.update(self._initial_query)
|
||||
return self._mongo_query
|
||||
|
||||
def ensure_index(self, key_or_list, drop_dups=False, background=False,
|
||||
**kwargs):
|
||||
"""Ensure that the given indexes are in place.
|
||||
|
||||
:param key_or_list: a single index key or a list of index keys (to
|
||||
construct a multi-field index); keys may be prefixed with a **+**
|
||||
or a **-** to determine the index ordering
|
||||
"""
|
||||
index_spec = self._document._build_index_spec(key_or_list)
|
||||
index_spec = index_spec.copy()
|
||||
fields = index_spec.pop('fields')
|
||||
index_spec['drop_dups'] = drop_dups
|
||||
index_spec['background'] = background
|
||||
index_spec.update(kwargs)
|
||||
|
||||
self._collection.ensure_index(fields, **index_spec)
|
||||
return self
|
||||
|
||||
def __call__(self, q_obj=None, class_check=True, slave_okay=False,
|
||||
read_preference=None, **query):
|
||||
"""Filter the selected documents by calling the
|
||||
@@ -150,87 +131,26 @@ class QuerySet(object):
|
||||
"""Returns all documents."""
|
||||
return self.__call__()
|
||||
|
||||
def ensure_index(self, **kwargs):
|
||||
"""Deprecated use :func:`~Document.ensure_index`"""
|
||||
msg = ("Doc.objects()._ensure_index() is deprecated. "
|
||||
"Use Doc.ensure_index() instead.")
|
||||
warnings.warn(msg, DeprecationWarning)
|
||||
self._document.__class__.ensure_index(**kwargs)
|
||||
return self
|
||||
|
||||
def _ensure_indexes(self):
|
||||
"""Checks the document meta data and ensures all the indexes exist.
|
||||
|
||||
.. note:: You can disable automatic index creation by setting
|
||||
`auto_create_index` to False in the documents meta data
|
||||
"""
|
||||
background = self._document._meta.get('index_background', False)
|
||||
drop_dups = self._document._meta.get('index_drop_dups', False)
|
||||
index_opts = self._document._meta.get('index_opts') or {}
|
||||
index_cls = self._document._meta.get('index_cls', True)
|
||||
|
||||
# determine if an index which we are creating includes
|
||||
# _cls as its first field; if so, we can avoid creating
|
||||
# an extra index on _cls, as mongodb will use the existing
|
||||
# index to service queries against _cls
|
||||
cls_indexed = False
|
||||
|
||||
def includes_cls(fields):
|
||||
first_field = None
|
||||
if len(fields):
|
||||
if isinstance(fields[0], basestring):
|
||||
first_field = fields[0]
|
||||
elif isinstance(fields[0], (list, tuple)) and len(fields[0]):
|
||||
first_field = fields[0][0]
|
||||
return first_field == '_cls'
|
||||
|
||||
# Ensure indexes created by uniqueness constraints
|
||||
for index in self._document._meta['unique_indexes']:
|
||||
cls_indexed = cls_indexed or includes_cls(index)
|
||||
self._collection.ensure_index(index, unique=True,
|
||||
background=background, drop_dups=drop_dups, **index_opts)
|
||||
|
||||
# Ensure document-defined indexes are created
|
||||
if self._document._meta['index_specs']:
|
||||
index_spec = self._document._meta['index_specs']
|
||||
for spec in index_spec:
|
||||
spec = spec.copy()
|
||||
fields = spec.pop('fields')
|
||||
cls_indexed = cls_indexed or includes_cls(fields)
|
||||
opts = index_opts.copy()
|
||||
opts.update(spec)
|
||||
self._collection.ensure_index(fields,
|
||||
background=background, **opts)
|
||||
|
||||
# If _cls is being used (for polymorphism), it needs an index,
|
||||
# only if another index doesn't begin with _cls
|
||||
if index_cls and '_cls' in self._query and not cls_indexed:
|
||||
self._collection.ensure_index('_cls',
|
||||
background=background, **index_opts)
|
||||
|
||||
# Add geo indicies
|
||||
for field in self._document._geo_indices():
|
||||
index_spec = [(field.db_field, pymongo.GEO2D)]
|
||||
self._collection.ensure_index(index_spec,
|
||||
background=background, **index_opts)
|
||||
|
||||
@classmethod
|
||||
def _reset_already_indexed(cls, document=None):
|
||||
"""Helper to reset already indexed, can be useful for testing purposes
|
||||
"""
|
||||
if document:
|
||||
cls.__already_indexed.discard(document)
|
||||
cls.__already_indexed.clear()
|
||||
"""Deprecated use :func:`~Document.ensure_indexes`"""
|
||||
msg = ("Doc.objects()._ensure_indexes() is deprecated. "
|
||||
"Use Doc.ensure_indexes() instead.")
|
||||
warnings.warn(msg, DeprecationWarning)
|
||||
self._document.__class__.ensure_indexes()
|
||||
|
||||
@property
|
||||
def _collection(self):
|
||||
"""Property that returns the collection object. This allows us to
|
||||
perform operations only if the collection is accessed.
|
||||
"""
|
||||
if self._document not in QuerySet.__already_indexed:
|
||||
# Ensure collection exists
|
||||
db = self._document._get_db()
|
||||
if self._collection_obj.name not in db.collection_names():
|
||||
self._document._collection = None
|
||||
self._collection_obj = self._document._get_collection()
|
||||
|
||||
QuerySet.__already_indexed.add(self._document)
|
||||
|
||||
if self._document._meta.get('auto_create_index', True):
|
||||
self._ensure_indexes()
|
||||
|
||||
return self._collection_obj
|
||||
|
||||
@property
|
||||
|
||||
Reference in New Issue
Block a user