Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix + test for #81

Making collection map_reduce properly handle ObjectId fields
  • Loading branch information...
commit 1bb7f96415e584ef1ac8ac9b98d1f3da4ea51550 1 parent 756121d
@baruchoxman baruchoxman authored
Showing with 28 additions and 4 deletions.
  1. +12 −3 mongomock/collection.py
  2. +16 −1 tests/test__mongomock.py
View
15 mongomock/collection.py
@@ -487,10 +487,16 @@ def map_reduce(self, map_func, reduce_func, out, full_response=False, query=None
function doMap(fnc, docList) {
var mappedDict = {};
function emit(key, val) {
- if(!mappedDict[key]) {
- mappedDict[key] = [];
+ if (key['$oid']) {
+ mapped_key = '$oid' + key['$oid'];
}
- mappedDict[key].push(val);
+ else {
+ mapped_key = key;
+ }
+ if(!mappedDict[mapped_key]) {
+ mappedDict[mapped_key] = [];
+ }
+ mappedDict[mapped_key].push(val);
}
mapper = eval('('+fnc+')');
var mappedList = new Array();
@@ -516,6 +522,9 @@ def map_reduce(self, map_func, reduce_func, out, full_response=False, query=None
doc_list = [json.dumps(doc, default=json_util.default) for doc in self.find(query)]
mapped_rows = map_ctx.call('doMap', map_func, doc_list)
reduced_rows = reduce_ctx.call('doReduce', reduce_func, mapped_rows)[:limit]
+ for reduced_row in reduced_rows:
+ if reduced_row['_id'].startswith('$oid'):
+ reduced_row['_id'] = ObjectId(reduced_row['_id'][4:])
reduced_rows = sorted(reduced_rows, key=lambda x: x['_id'])
if full_response:
full_dict['counts']['input'] = len(doc_list)
View
17 tests/test__mongomock.py
@@ -667,7 +667,7 @@ def test__map_reduce_full_response(self):
for doc in getattr(self.db, result['result']).find():
self.assertIn(doc, self.expected_results)
- def test__map_reduct_with_query(self):
+ def test__map_reduce_with_query(self):
expected_results = [{'_id': 'mouse', 'value': 1},
{'_id': 'dog', 'value': 2},
{'_id': 'cat', 'value': 2}]
@@ -699,6 +699,21 @@ def test__inline_map_reduce_full_response(self):
for doc in result['result']:
self.assertIn(doc, self.expected_results)
+ def test__map_reduce_with_object_id(self):
+ obj1 = ObjectId()
+ obj2 = ObjectId()
+ data = [{"x": 1, "tags": [obj1, obj2]},
+ {"x": 2, "tags": [obj1]}]
+ for item in data:
+ self.db.things_with_obj.insert(item)
+ expected_results = [{'_id': obj1, 'value': 2},
+ {'_id': obj2, 'value': 1}]
+ result = self.db.things_with_obj.map_reduce(self.map_func, self.reduce_func, 'myresults')
+ self.assertTrue(isinstance(result, mongomock.Collection))
+ self.assertEqual(result.name, 'myresults')
+ self.assertEqual(result.count(), 2)
+ for doc in result.find():
+ self.assertIn(doc, expected_results)
def _LIMIT(*args):
return lambda cursor: cursor.limit(*args)
Please sign in to comment.
Something went wrong with that request. Please try again.