在 $where 中调用 db.system.js 函数 [英] Calling db.system.js Function in $where

查看:53
本文介绍了在 $where 中调用 db.system.js 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为一个基本的例子,我保存了这个函数:

As a basic example, I have this function saved:

db.system.js.save({_id: "sum", value: function (x, y) { return x + y; }});

但是当我尝试调用 $where 时,我得到的引用不存在.

But when I try to called in the $where I get a Reference not exist.

<?php

$collection = $link -> selectCollection('foo' ,'bar');
$collection -> find(array(
'$where' =>'sum(this.x, this.y)'
));

?>

和错误

ReferenceError: sum is not defined :

我应该保存它还是以其他方式访问它?

Should I save it or access it another way?

推荐答案

您是否在 PHP 代码中连接到使用 shell 连接到的同一个数据库命名空间?我觉得不是!

Are you connecting to the same database namespace in your PHP code that you connected to using the shell? I think not!

无论如何你误解了$where的概念 在这种情况下,因为除了集合中已经包含的数据之外,您只能评估而不是返回修改后的结果.

Anyway you misunderstand the concept of $where in this context, since you can only evaluate and not return modified results other than the data already contained in the collection.

实际上可以返回与现有文档不同的东西的唯一东西是 .mapReduce().aggregate().

The only things that can actually return something different than the existing documents are .mapReduce() and .aggregate().

所以为了演示,在相同的命名空间"中,如果你定义了一个集合:

So to demonstrate, in the "same namespace" if you define a collection:

db.djunk.insert({ "x": 1, "y": 2 })

然后运行一个 .mapReduce()

db.dbjunk.mapReduce(
    function() {
        emit(this._id, sum(this.x,this.y))
    },
    function() {}, // does nothing here where already unique
    { "out": { "inline": 1 } }
)

那将返回实际求和结果:

{
    "_id" : ObjectId("571a9bb951d042a7a896fd92"),
    "value" : 3
}

$where 所能做的就是逻辑地"选择文档:

All that $where can do, is "logically" select the document:

db.djunk.find(function() {
    return sum(this.x,this.y) > 3
})

不满足条件.

但当然,您确实不需要这样做,并且通常应该尽可能避免任何 JavaScript 的服务器执行.它比原生操作符慢得多,而且你可以用原生操作符做很多事情.

But of course you really don't need to do this, and should generally be avoiding any server execution of JavaScript where possible. It's much slower than native operators, and you can do quite a bit with native operators.

所以代替 .mapReduce() 调用 .aggregate():

db.djunk.aggregate([
    { "$project": {
        "total": { "$add": [ "$x", "$y" ] }
    }}
])

而不是 JavaScript 评估,再次调用 .aggregate(),使用 $redact 用于逻辑"过滤:

And instead of JavaScript evaluation, call .aggregate() again, with $redact for "logical" filtering:

db.djunk.aggregate([
    { "$redact": {
        "$cond": {
            "if": { "$gt": [ { "$add": [ "$x", "$y" ] }, 3 ] },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }      
    }}
])

因此,在大多数情况下,总是有更好的替代方法来使用 JavaScript 评估.当然,在真正需要 JavaScript 评估的情况下,实际上很少有真正需要服务器存储函数的情况.

So in most cases there is always a better alternative to using JavaScript evaluation. And certainly there are actually very few cases to really need server stored functions in the cases where JavaScript evaluation is actually required.

但是您在这里的基本错误将是因为该函数位于不同的命名空间中,或者您确实在两者之间重新启动了服务器.但总体而言,您可能无论如何都不应该使用存储函数.

But your basic error here will be because the function was in a different namespace, or indeed that you restarted the server in between. But the overall point is you probably should not be using stored functions anyway.

这篇关于在 $where 中调用 db.system.js 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆