diff --git a/AUTHORS b/AUTHORS index e88de8c6..70720f09 100644 --- a/AUTHORS +++ b/AUTHORS @@ -16,8 +16,6 @@ Dervived from the git logs, inevitably incomplete but all of whom and others have submitted patches, reported bugs and generally helped make MongoEngine that much better: - * Harry Marr - * Ross Lawley * blackbrrr * Florian Schlachter * Vincent Driessen @@ -171,4 +169,5 @@ that much better: * ygbourhis (https://github.com/ygbourhis) * Bob Dickinson (https://github.com/BobDickinson) * Michael Bartnett (https://github.com/michaelbartnett) - * Alon Horev (https://github.com/alonho) \ No newline at end of file + * Alon Horev (https://github.com/alonho) + * Kelvin Hammond (https://github.com/kelvinhammond) diff --git a/mongoengine/queryset/queryset.py b/mongoengine/queryset/queryset.py index c040e391..690e3f03 100644 --- a/mongoengine/queryset/queryset.py +++ b/mongoengine/queryset/queryset.py @@ -1068,7 +1068,22 @@ class QuerySet(object): """ map_func = Code(""" function() { - emit(1, this[field] || 0); + function deepFind(obj, path) { + var paths = path.split('.') + , current = obj + , i; + + for (i = 0; i < paths.length; ++i) { + if (current[paths[i]] == undefined) { + return undefined; + } else { + current = current[paths[i]]; + } + } + return current; + } + + emit(1, deepFind(this, field) || 0); } """, scope={'field': field}) @@ -1098,8 +1113,24 @@ class QuerySet(object): """ map_func = Code(""" function() { - if (this.hasOwnProperty(field)) - emit(1, {t: this[field] || 0, c: 1}); + function deepFind(obj, path) { + var paths = path.split('.') + , current = obj + , i; + + for (i = 0; i < paths.length; ++i) { + if (current[paths[i]] == undefined) { + return undefined; + } else { + current = current[paths[i]]; + } + } + return current; + } + + val = deepFind(this, field) + if (val !== undefined) + emit(1, {t: val || 0, c: 1}); } """, scope={'field': field}) diff --git a/tests/queryset/queryset.py b/tests/queryset/queryset.py index 566c14e4..9495a25e 100644 --- a/tests/queryset/queryset.py +++ b/tests/queryset/queryset.py @@ -30,12 +30,17 @@ class QuerySetTest(unittest.TestCase): def setUp(self): connect(db='mongoenginetest') + class PersonMeta(EmbeddedDocument): + weight = IntField() + class Person(Document): name = StringField() age = IntField() + person_meta = EmbeddedDocumentField(PersonMeta) meta = {'allow_inheritance': True} Person.drop_collection() + self.PersonMeta = PersonMeta self.Person = Person def test_initialisation(self): @@ -2208,6 +2213,19 @@ class QuerySetTest(unittest.TestCase): self.Person(name='ageless person').save() self.assertEqual(int(self.Person.objects.average('age')), avg) + # dot notation + self.Person(name='person meta', person_meta=self.PersonMeta(weight=0)).save() + self.assertAlmostEqual(int(self.Person.objects.average('person_meta.weight')), 0) + + for i, weight in enumerate(ages): + self.Person(name='test meta%i', person_meta=self.PersonMeta(weight=weight)).save() + + self.assertAlmostEqual(int(self.Person.objects.average('person_meta.weight')), avg) + + self.Person(name='test meta none').save() + self.assertEqual(int(self.Person.objects.average('person_meta.weight')), avg) + + def test_sum(self): """Ensure that field can be summed over correctly. """ @@ -2220,6 +2238,14 @@ class QuerySetTest(unittest.TestCase): self.Person(name='ageless person').save() self.assertEqual(int(self.Person.objects.sum('age')), sum(ages)) + for i, age in enumerate(ages): + self.Person(name='test meta%s' % i, person_meta=self.PersonMeta(weight=age)).save() + + self.assertEqual(int(self.Person.objects.sum('person_meta.weight')), sum(ages)) + + self.Person(name='weightless person').save() + self.assertEqual(int(self.Person.objects.sum('age')), sum(ages)) + def test_distinct(self): """Ensure that the QuerySet.distinct method works. """