Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript MongoDB map reduce(通过nodejs):如何在scopeObj中包含复杂的模块(具有依赖项)?_Javascript_Node.js_Mongodb_Npm_Mapreduce - Fatal编程技术网

Javascript MongoDB map reduce(通过nodejs):如何在scopeObj中包含复杂的模块(具有依赖项)?

Javascript MongoDB map reduce(通过nodejs):如何在scopeObj中包含复杂的模块(具有依赖项)?,javascript,node.js,mongodb,npm,mapreduce,Javascript,Node.js,Mongodb,Npm,Mapreduce,我正在为mongodb数据库开发一个复杂的map reduce过程。我将一些更复杂的代码拆分为模块,然后通过将其包含在我的scopeObj中,使其可用于map/reduce/finalize函数,如下所示: const scopeObj = { userCalculations: require('../lib/userCalculations') } function myMapFn() { let userScore = userCalculations.ove

我正在为mongodb数据库开发一个复杂的map reduce过程。我将一些更复杂的代码拆分为模块,然后通过将其包含在我的
scopeObj
中,使其可用于map/reduce/finalize函数,如下所示:

  const scopeObj = {
    userCalculations: require('../lib/userCalculations')
  }

  function myMapFn() {
    let userScore = userCalculations.overallScoreForUser(this)
    emit({
      'Key': this.userGroup
    }, {
      'UserCount': 1,
      'Score': userScore
    })
  }

  function myReduceFn(key, objArr) { /*...*/ }

  db.collection('userdocs').mapReduce(
    myMapFn,
    myReduceFn,
    {
      scope: scopeObj,
      query: {},
      out: {
        merge: 'userstats'
      }
    },
    function (err, stats) {
      return cb(err, stats);
    }
  )
…这一切都很好。直到最近,我还一直认为不可能将模块代码包含到map reduce
scopeObj
中,但事实证明,这只是因为我试图包含的模块都依赖于其他模块。完全独立的模块似乎工作正常

这就引出了我的问题。我如何——或者,就此而言,我应该——将更复杂的模块,包括我从npm中提取的东西,合并到我的map reduce代码中?我有一个想法是使用Browserify或类似的工具将我所有的依赖项拉到一个文件中,然后以某种方式包含它。。。但我不确定这样做的正确方式是什么。我也不确定我的map-reduce代码会严重膨胀到什么程度,这(出于明显的原因)必须是有效的

有没有人有做这种事情的经验?如果有,结果如何?我是不是走了一条不好的路

更新:澄清我试图解决的问题: 在上面的代码中,
require('../lib/userCalculations')
由节点执行——它读取文件
。/lib/userCalculations.js
,并将该文件的
模块的内容分配给
scopeObj.userCalculations
。但是假设在
userCalculations.js
中有一个调用
require(…)
。那个调用实际上还没有执行。因此,当我尝试在Map函数中调用
userCalculations.overallScoreForUser()
时,MongoDB会尝试执行
require
函数。并且在mongo上没有定义
require

例如,Browserify通过将所有必需模块中的所有代码编译成一个javascript文件来处理此问题,无需调用
require
,因此它可以在浏览器中运行。但这在这里并不完全有效,因为我需要作为结果代码本身成为一个模块,我可以像在代码示例中使用
userCalculations
一样使用它。也许有一种奇怪的方式运行browserify,我不知道?或者其他一些工具,只是将整个模块层次结构“展平”为单个模块


希望这能澄清一点。

作为一个一般性的回答,你的问题的答案是:我如何——或者说,我应该——将更复杂的模块,包括我从npm提取的东西,合并到我的map reduce代码中是否,您不能在计划发送到MongoDB以进行mapReduce作业的节点代码中安全地包含复杂模块

您自己也提到了这个问题-嵌套的
require
语句。现在,require是sync,但如果您在其中有嵌套函数,这些require调用将在调用时才会执行,此时MongoDB VM将抛出

考虑以下三个文件的示例:
data.json
dep.js
main.js

// data.json - just something we require "lazily"
false

// dep.js -- equivalent of your userCalculations
module.exports = {
  isValueTrue() {
    // The problem: nested require
    return require('./data.json');
  }
}


// main.js - from here you send your mapReduce to MongoDB.
// require dependency instantly
const calc = require('./dep.js');
// require is synchronous, the effectis the same if you do:
//   const calc = (function () {return require('./dep.js')})();

console.log('Calc is loaded.');
// Let's mess with unwary devs
require('fs').writeFileSync('./data.json', 'false');

// Is calc.isValueTrue() true or false here?
console.log(calc.isValueTrue());
作为一般解决办法,这是不可行的。虽然绝大多数模块可能没有嵌套的
require
语句、HTTP调用,甚至没有内部、服务调用、全局变量和类似的调用,但也有一些模块是这样做的。你不能保证这会起作用

现在,作为本地实现的一个例子:例如,您需要NPM模块的特定版本,您已经使用此技术进行了良好的测试,并且您知道它会起作用,或者您自己发布了它们,这在某种程度上是可行的

然而,即使在这种情况下,如果这是一个团队的努力,那么一定会有一个开发人员不知道您的依赖关系在哪里使用,或者如何使用全局变量(不是故意的,而是故意的,例如他们错误地计算了
这个
),或者根本不知道他们所做的任何事情的含义。如果您有强大的集成测试套件,您可以对此加以防范,但问题是,这是不可预测的。我个人认为,当你可以在不可预测和可预测之间做出选择时,几乎总是应该使用可预测

现在,如果您明确说明了在MongoDB mapReduce中使用某个库的目的,这将起作用。您必须很好地防范各种干扰和问题,并拥有强大的测试基础设施,但我会确保在感到安全之前,目的是明确的。但是,当然,如果您使用的是非常复杂的东西,需要几个npm包来完成,那么您可以直接在MongoDB服务器上使用这些功能,或者您可以使用更适合此目的的映射还原,或者类似的方法


总而言之:作为一个有目的地构建的库,它有明确的任务声明,将与node和MongoDB mapReduce一起使用,我将确保我的测试涵盖所有关键和重要的功能,然后导入这样的npm包。否则,我将不使用或不推荐这种方法。

我不知道有关访问模块的答案,但是您是否愿意考虑使用聚合框架重写Map Reduce代码的替代方案。如果是,请查看是否可以从其他模块发布map和reduce中的相关代码。More@Veeram除非我遗漏了什么,否则我认为聚合框架对我不起作用——我需要能够在
reduce
阶段进行一些非常复杂的计算,并且我还需要能够进行增量更新(即“合并”样式的输出)。你对依赖层次结构有多大的“控制”?意味着是否存在任何隐藏的依赖项/第三方代码?我不确定你的问题是否正确,但如果是,它是可以解决的。@Ja