作为一个基本的例子,我保存了这个功能:
db.system.js.save({_id: "sum", value: function (x, y) { return x + y; }});
但是当我试图调用$时,我得到的参考文献不存在。
<?php
$collection = $link -> selectCollection('foo' ,'bar');
$collection -> find(array(
'$where' =>'sum(this.x, this.y)'
));
?>
错误
ReferenceError: sum is not defined :
我应该保存还是以其他方式访问它?
答案 0 :(得分:1)
您是否在使用shell连接到的PHP代码中连接到相同的数据库命名空间?我想不是!
无论如何,你在这种情况下误解了$where
的概念,因为你只能评估而不是返回修改后的结果,而不是已包含在集合。
唯一能够实际返回与现有文档不同的内容的是.mapReduce()
和.aggregate()
。
如果你定义一个集合,那么在“相同的命名空间”中进行演示:
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
可以做的所有事情都是“逻辑地”选择文档:
db.djunk.find(function() {
return sum(this.x,this.y) > 3
})
哪个不符合条件。
但是当然你真的不需要这样做,并且通常应尽可能避免任何服务器执行JavaScript。它比本机运算符慢得多,你可以用本机运算符做很多事情。
而不是.mapReduce()
致电.aggregate()
:
db.djunk.aggregate([
{ "$project": {
"total": { "$add": [ "$x", "$y" ] }
}}
])
而不是JavaScript评估,请再次致电.aggregate()
,使用$redact
进行“逻辑”过滤:
db.djunk.aggregate([
{ "$redact": {
"$cond": {
"if": { "$gt": [ { "$add": [ "$x", "$y" ] }, 3 ] },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
因此,在大多数情况下,使用JavaScript评估总是有更好的选择。当然,在实际需要进行JavaScript评估的情况下,实际上很少需要服务器存储函数。
但是你的基本错误是因为函数位于不同的命名空间中,或者确实是你重新启动了服务器。但总的来说,你可能不应该使用存储的函数。