Enable covered indexes for simple documents.

Refs #444
This commit is contained in:
Ross Lawley 2012-03-02 13:42:24 +00:00
parent bdf7187d5c
commit 32fc4152a7
3 changed files with 39 additions and 4 deletions

View File

@ -5,6 +5,7 @@ Changelog
Changes in 0.6 Changes in 0.6
============== ==============
- Added support for covered indexes when inheritance is off
- No longer always upsert on save for items with a '_id' - No longer always upsert on save for items with a '_id'
- Error raised if update doesn't have an operation - Error raised if update doesn't have an operation
- DeReferencing is now thread safe - DeReferencing is now thread safe

View File

@ -273,16 +273,20 @@ class Q(QNode):
class QueryFieldList(object): class QueryFieldList(object):
"""Object that handles combinations of .only() and .exclude() calls""" """Object that handles combinations of .only() and .exclude() calls"""
ONLY = True ONLY = 1
EXCLUDE = False EXCLUDE = 0
def __init__(self, fields=[], value=ONLY, always_include=[]): def __init__(self, fields=[], value=ONLY, always_include=[]):
self.value = value self.value = value
self.fields = set(fields) self.fields = set(fields)
self.always_include = set(always_include) self.always_include = set(always_include)
self._id = None
def as_dict(self): def as_dict(self):
return dict((field, self.value) for field in self.fields) field_list = dict((field, self.value) for field in self.fields)
if self._id is not None:
field_list['_id'] = self._id
return field_list
def __add__(self, f): def __add__(self, f):
if not self.fields: if not self.fields:
@ -298,6 +302,9 @@ class QueryFieldList(object):
self.value = self.ONLY self.value = self.ONLY
self.fields = f.fields - self.fields self.fields = f.fields - self.fields
if '_id' in f.fields:
self._id = f.value
if self.always_include: if self.always_include:
if self.value is self.ONLY and self.fields: if self.value is self.ONLY and self.fields:
self.fields = self.fields.union(self.always_include) self.fields = self.fields.union(self.always_include)

View File

@ -714,7 +714,6 @@ class DocumentTest(unittest.TestCase):
self.assertEqual(info.keys(), ['_types_1_user_guid_1', '_id_', '_types_1_name_1']) self.assertEqual(info.keys(), ['_types_1_user_guid_1', '_id_', '_types_1_name_1'])
Person.drop_collection() Person.drop_collection()
def test_embedded_document_index(self): def test_embedded_document_index(self):
"""Tests settings an index on an embedded document """Tests settings an index on an embedded document
""" """
@ -788,6 +787,34 @@ class DocumentTest(unittest.TestCase):
self.assertEquals(len(User._geo_indices()), 2) self.assertEquals(len(User._geo_indices()), 2)
def test_covered_index(self):
"""Ensure that covered indexes can be used
"""
class Test(Document):
a = IntField()
meta = {
'indexes': ['a'],
'allow_inheritance': False
}
Test.drop_collection()
obj = Test(a=1)
obj.save()
# Need to be explicit about covered indexes as mongoDB doesn't know if
# the documents returned might have more keys in that here.
query_plan = Test.objects(id=obj.id).exclude('a').explain()
self.assertFalse(query_plan['indexOnly'])
query_plan = Test.objects(id=obj.id).only('id').explain()
self.assertTrue(query_plan['indexOnly'])
query_plan = Test.objects(a=1).only('a').exclude('id').explain()
self.assertTrue(query_plan['indexOnly'])
def test_hint(self): def test_hint(self):
class BlogPost(Document): class BlogPost(Document):