自定义函数计算列mongodb投影

Man*_*ieh 2 mongodb

我正在尝试使用投影来获取在集合中的列上使用自定义函数计算的列,但我无法想办法如何做到这一点.我能做的是:

db.collection.aggregate([$project:{column1:1, calculatedCol: {$literal:[ jaro_Winkler("how to access column name")]}] )
Run Code Online (Sandbox Code Playgroud)

代码可能有语法错误,因为我现在没有代码.

Bla*_*ven 17

您似乎认为可以在聚合管道中调用JavaScript函数,但您无法执行此操作.您错误地认为变量的实际"插值"来自函数结果,以便在管道中执行.

例如,如果我这样做:

var getNumbers = function() { return [ 1,2,3 ] };
Run Code Online (Sandbox Code Playgroud)

然后我称之为:

db.collection.aggregate([
    { "$project": {
        "mynums": getNumbers()
    }}  
])
Run Code Online (Sandbox Code Playgroud)

那么在JavaScript shell中实际发生的事情是将值"插入"和"在"指令发送到服务器之前,如下所示:

db.collection.aggregate([
    { "$project": {
        "mynums": [1,2,3]
    }}  
])
Run Code Online (Sandbox Code Playgroud)

为了进一步证明,在服务器上"仅"存储一个函数:

db.system.js.save({ "_id": "hello", "value": function() { return "hello" } })
Run Code Online (Sandbox Code Playgroud)

然后尝试运行聚合语句:

db.collection.aggregate([
    { "$project": {
        "greeting": hello()
    }}  
])
Run Code Online (Sandbox Code Playgroud)

这将导致异常:

E QUERY [main] ReferenceError:hello未在(shell)中定义:1:69

这是因为执行发生在"客户端"而不是"服务器"上,并且客户端上不存在该功能.

聚合框架无法运行JavaScript,因为它没有这样做的规定.所有操作都在本机代码中执行,不会调用任何JavaScript引擎.因此,您可以在那里使用运算符:

db.collection.aggregate([
    { "$project": {
        "total": { "$add": [ 1, 2 ] },
        "field_total": { "$subtract": [ "$gross", "$tax" ] }
    }}  
])   
Run Code Online (Sandbox Code Playgroud)

如果你不能使用运算符来实现结果,那么运行JavaScript代码的唯一方法就是运行mapReduce,当然使用JavaScript引擎来连接集合中的数据.从那里,如果需要,您还可以在逻辑中引用服务器端功能:

{ "key": 1, "value": 1 },
{ "key": 1, "value": 2 },
{ "key": 1, "value": 3 }

db.system.js.save({ "_id": "square", "value": function(num) { return num * num } })

db.collection.mapReduce(
    function() {
        emit(this.key,square(this.value))
    },
    function(key,values) {
        return Array.sum(values);
    },
    { "out": { "inline": 1 } }
)
Run Code Online (Sandbox Code Playgroud)

返回:

{
    "_id": 1,
    "value": 14
}
Run Code Online (Sandbox Code Playgroud)

所以这不是关于"如何传递字段值",而是关于聚合框架不以任何方式支持JavaScript的事实,并且您认为发生的事实并非如此.