(#6099) - use Map/Set in viewCleanup()
diff --git a/packages/node_modules/pouchdb-mapreduce/src/index.js b/packages/node_modules/pouchdb-mapreduce/src/index.js
index af8b634..cc2691e 100644
--- a/packages/node_modules/pouchdb-mapreduce/src/index.js
+++ b/packages/node_modules/pouchdb-mapreduce/src/index.js
@@ -771,23 +771,27 @@
 
 function localViewCleanup(db) {
   return db.get('_local/mrviews').then(function (metaDoc) {
-    var docsToViews = {};
+    var docsToViews = new Map();
     Object.keys(metaDoc.views).forEach(function (fullViewName) {
       var parts = parseViewName(fullViewName);
       var designDocName = '_design/' + parts[0];
       var viewName = parts[1];
-      docsToViews[designDocName] = docsToViews[designDocName] || {};
-      docsToViews[designDocName][viewName] = true;
+      var views = docsToViews.get(designDocName);
+      if (!views) {
+        views = new Set();
+        docsToViews.set(designDocName, views);
+      }
+      views.add(viewName);
     });
     var opts = {
-      keys : Object.keys(docsToViews),
+      keys : mapToKeysArray(docsToViews),
       include_docs : true
     };
     return db.allDocs(opts).then(function (res) {
       var viewsToStatus = {};
       res.rows.forEach(function (row) {
-        var ddocName = row.key.substring(8);
-        Object.keys(docsToViews[row.key]).forEach(function (viewName) {
+        var ddocName = row.key.substring(8); // cuts off '_design/'
+        docsToViews.get(row.key).forEach(function (viewName) {
           var fullViewName = ddocName + '/' + viewName;
           /* istanbul ignore if */
           if (!metaDoc.views[fullViewName]) {
diff --git a/tests/mapreduce/test.persisted.js b/tests/mapreduce/test.persisted.js
index 39d034d..18af2f8 100644
--- a/tests/mapreduce/test.persisted.js
+++ b/tests/mapreduce/test.persisted.js
@@ -460,6 +460,58 @@
       });
     }
 
+    it('test docs with reserved IDs', function () {
+      var db = new PouchDB(dbName);
+
+      var docs = [
+        {_id: 'constructor'},
+        {_id: 'isPrototypeOf'},
+        {_id: 'hasOwnProperty'},
+        {
+          _id : '_design/view',
+          views : {
+            view : {
+              map : "function(doc){emit(doc._id);}"
+            }
+          }
+        }
+      ];
+      return db.bulkDocs(docs).then(function () {
+        return db.query('view/view', {include_docs: true});
+      }).then(function (res) {
+        var rows = res.rows.map(function (row) {
+          return {
+            id: row.id,
+            key: row.key,
+            docId: row.doc._id
+          };
+        });
+        assert.deepEqual(rows, [
+          { "id": "constructor",
+            "key": "constructor",
+            "docId": "constructor"
+          },
+          {
+            "id": "hasOwnProperty",
+            "key": "hasOwnProperty",
+            "docId": "hasOwnProperty"
+          },
+          {
+            "id": "isPrototypeOf",
+            "key": "isPrototypeOf",
+            "docId": "isPrototypeOf"
+          }
+        ]);
+        return db.viewCleanup();
+      }).then(function () {
+        return db.get('_design/view');
+      }).then(function (doc) {
+        return db.remove(doc);
+      }).then(function () {
+        return db.viewCleanup();
+      });
+    });
+
     it('should handle user errors in design doc names', function () {
       var db = new PouchDB(dbName);
       return db.put({