前言:
为了获得干净有效的代码,我想在我的MapReduce Mongo脚本中使用外部函数。
问题:
给定我们有以下映射函数(CoffeeScript语法):
map: ->
key = foo(@field)
emit(key, value)
调用外部函数"foo"引发错误
➜ rake mongo:mapreduce
MongoDB shell version: 2.0.5
connecting to: localhost:27017/connect_development
{
"assertion" : "map invoke failed: JS Error: ReferenceError: foo is not defined nofile_b:2",
"assertionCode" : 9014,
"errmsg" : "db assertion failure",
"ok" : 0
}
同样,我们将返回减少上下文调用。
难闻的气味决策 - 自调用匿名函数:
map: ->
key = ( (field)->
# some business logic
)(@field)
emit(key, value)
自调用匿名函数可能非常大且无法有效测试,并可能导致内存泄漏(不确定)。
如何解决这个问题?
上级:
当我说"外部函数"时,是指在同一个文件(在同一类中)中声明的函数,其中包含"map/reduce"函数。当然,它是在服务器端调用的。
Map/reduce 函数必须在另一个上下文中的数据库服务器上运行,因此它们不能接触任何"外部"内容。
内联使用匿名函数没有错,它们非常便宜 - 只是避免深度递归。CoffeeScript 具有用于创建闭包的语法,您可能想要使用:
map: ->
key = do =>
k = @field.doSomething()
return k
emit key, value
Map/Reduce代码在MongoDB服务器上执行。 您可以选择在服务器端存储可从 Map/Reduce 调用的函数,但最佳实践建议将函数与其余代码一起保留在版本控制中。 匿名函数在 JavaScript 中常用,应该不是问题。