灵活的JavaScript函数(适用于MongoDB)

时间:2010-09-15 20:37:18

标签: javascript node.js mongodb

我正在为MongoDB开发一些Map / Reduce查询,并尝试执行以下操作(简而言之)。

m = function()
{
    this.convert = function(val)
    {
        return val+1;
    }

    emit(convert(this.age), this.doesWearGlasses);
}

r = function(k, v)
{
    count = 0;
    for(var i = 0; i < v.length; i++)
    {
        count += v[i];
    }
    return count;
}

if(tuned)
{
    m.convert = function(val)
    {
        return val;
    }
}

/**
* Continue to running the M/R query
*/

应该注意的是,我将其写为Node.js应用程序,但我认为大多数相同的主体都适用于任何JavaScript。

问题是我不认为我可以在不创建对象的情况下更改它,ala mTmp = new m();,但我不能,因为emit()(以及其他所有内容)未定义。

我尝试使用m.prototype.convert = function,但这不起作用。 m.toString()的值不会改变。

2 个答案:

答案 0 :(得分:1)

认为您尝试加入m(地图函数)的行为会有所不同,具体取决于是否设置了tuned。是吗?

不幸的是,由于map和reduce函数都只是作为函数体的字符串传递给MongoDB,因此它们无法访问任何外部代码或数据 - 因此您在函数上设置的任何属性都会赢得'当它被执行时就在那里。

如果我理解正确,我认为这是你最好的三个选择:

  1. 为每种情况定义不同版本的m

  2. m汇总为一个字符串,根据tuned的值,插入正确的代码块。

  3. m根据变量决定行为方式,如下所示:

    m = function()
    {
        var result;
        if (tuned) {
            result = this.age;
        } else {
            result = this.age + 1;
        }
        emit(convert(this.age), this.doesWearGlasses);
    }
    

    ...当你致电tuned时,给mapReduce变量在MongoDB中第二次生命:

    collection.mapReduce(m, r, { scope: { tuned: tuned } });
    

    (FWIW,如果不同之处,实际上就是这么简单,你可以这样写m代替:)

    m = function()
    {
        emit(convert(tuned ? this.age : this.age + 1), this.doesWearGlasses);
    }
    
  4. ...如果你的意思不同,请告诉我。

答案 1 :(得分:0)

由于您在定义prototype函数后调用构造函数,this.convert将覆盖已定义的原型函数。

您可以覆盖整个m构造函数:

m = function()
{
    this.convert = function(val)
    {
        return val+1;
    }
}

if(tuned) {
    m = (function(mOld) {
        return function()
        {
            mOld.apply(this, arguments);
            this.convert = function(val){ return val; }
        }
    })(m);
}

// Test code
function doStuff(obj) {
    alert(obj.toString());
}

var mObj = new m();
doStuff(mObj);

它应该可以工作,但我不知道它可能会对你的实际脚本产生什么影响。

请注意,它使用self-invocation模式,这会创建一个闭包。

我添加了测试代码,证明这可以在OP中给出约束。