4

我对如何在 mongodb shell 中使用闭包有点困惑。

我想创建一个我可以在开发过程中专门使用的功能,以通过它的一部分快速查找文档_id

该函数应返回一个$where进行必要匹配的选择器。
我想这样写:

var id = function(pattern, selector) {
    return Object.extend({
        $where: function() {return (this._id + "").indexOf(pattern) != -1;}
    }, selector);
};

但是当我尝试它时,我收到以下错误:

db.mycollection.find(id("ab1"));
error: {
        "$err" : "JavaScript execution failed: ReferenceError: pattern is not defined near ').indexOf(pattern) ' ",
        "code" : 16722
}

手动调用$where似乎确实很奇怪:

id("ell").$where.call({_id: "hello"}); // true

我只能将其视为使其工作的解决方案,但这显然很糟糕。
澄清一下:这种方法new Function效果很好,但我不喜欢它,因为上述方法也应该有效。

var id = function(pattern, selector){
    return Object.extend({
        $where: new Function("return (this._id + '').indexOf('" + pattern + "') != -1;")
    }, selector);
};
  • 为什么我的闭包不起作用,闭包在 mongodb shell 中起作用吗?
  • 额外问题:我可以在用户配置文件的某处注册此功能以自动加载吗?
4

1 回答 1

2

似乎 MongoDB shell 序列化(在本例中为字符串化)$where函数对象,以便将它们发送到服务器。

JavaScript 中的函数不仅仅是它的函数代码——它是闭包的一部分,它包括函数代码本身和函数的变量引用环境,用于访问非局部变量。函数序列化后,它会被反序列化并在不同的引用环境下执行。当函数试图引用pattern时,它要求pattern在一个完全不同的引用环境中,它没有pattern变量。

这就是您的文字字符串函数起作用的原因。该函数包含 的实际值pattern,而不是变量标识符pattern

请参阅此 MongoDB bug,其中解释了:

如果函数是在本地评估的,那将起作用,但闭包不会自动发送。

在 babble 中它曾经是,但不是在 shell 中。

这表明您的代码可能在 shell 之外工作,但我对 Mongo 内部的了解还不够,无法确定。

于 2013-07-01T14:15:36.820 回答