Mongodb cannot run map reduce without the js engine

五迷三道 提交于 2019-12-11 04:17:26

问题


I deployed a nodejs app on appcloud with mongodb as service, I would like to use mapReduce for some queries but I got this error:

2016-10-21 15:45:52 [APP/0] ERR ERR! { [MongoError: cannot run map reduce without the js engine]

Is it supported on swisscom appcloud or what?

This is my controller (an extract):

'use strict';

const mongo = require('../mongoclient');
const paramsParser = require('../paramsParser');
const log = require('npmlog');
const faker = require('faker');
const _ = require('lodash');

const datapoints = function (router) {

  const map = function () {
    var payload = this.payload;
    if (payload) {
      payload = payload.toLowerCase().split(" ");
      for (var i = payload.length - 1; i >= 0; i--) {
        payload[i] = payload[i].replace(/[^\w\s]|_/g, "").replace(/\s+/g, " ");
        if (payload[i] && payload[i].length > 7) {
          emit(payload[i], 1); // store a 1 for each word
        }
      }
    }
  }

  const reduce = function(key, values) {
    var count = 0;
    values.forEach(function (v) {
      count += v;
    });
    return count;
  }
  
  router.get('/counts', function (req, res) {
    const filters = paramsParser.parse(req.query);

    mongo.mapReduce(map, reduce, filters)
      .then(function (data) {
        const topics = data
          .sort((a, b) => b.value - a.value)
          .slice(0, 10)
          .map(function(topic) {
            return { id: faker.random.uuid(), title: topic._id, score: topic.value }
          });
        res.json(topics);
      })
      .catch(function(err) {
        log.error(err);
        res.sendStatus(500);
      });
  });

};

module.exports = datapoints;

function mapReduce(map, reduce, filters) {
  filters = filters ? filters : defaults;
  return new Promise(function(resolve, reject) {
    client.connect(uri(), function(err, db) {
      db.collection(collection)
        .mapReduce(map, reduce, { out: { inline: 1 }, query: filters.find, limit: filters.pageSize }, function(err, docs) {
          if (err) {
            reject(err);
          }
          resolve(docs);
        });
    });
  });
}

回答1:


You are using Swisscom's Docker based MongoDB service.

Swisscom started mongod with security.javascriptEnabled

Enables or disables the server-side JavaScript execution. When disabled, you cannot use operations that perform server-side execution of JavaScript code, such as the $where query operator, mapReduce command and the db.collection.mapReduce() method, group command and the db.collection.group() method.

Swisscom enabled that flag because of security. It's a best practise for hardening MongoDB. Swisscom is open for technical arguments and discussions about that. Maybe Swisscom misses an important fact?

security:
   authorization: enabled
   javascriptEnabled: false

Swisscom offers an other MongoDB service (not in docker container, 3 dedicated VMs with replication). There you don't have this limitation.

$ cf m -s mongodbent
Getting service plan information for service mongodbent as admin...
OK

service plan   description                                                                                                 free or paid   
small3rs       Replica Set with 3 data bearing nodes with 32 GB memory, 320 GB storage, unlimited concurrent connections   paid   
medium3rs      Replica Set with 3 data bearing nodes with 48 GB memory, 480 GB storage, unlimited concurrent connections   paid   
large3rs       Replica Set with 3 data bearing nodes with 64 GB memory, 640 GB storage, unlimited concurrent connections   paid 

With this plan you will receive Enterprise version of MongoDB and access to Ops Manager. In Ops Manager you will see nice HTML5 graphs with MongoDB metrics. It's nice GUI frontend for db.runCommand( { serverStatus: 1 } ) with history.



来源:https://stackoverflow.com/questions/40179448/mongodb-cannot-run-map-reduce-without-the-js-engine

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!