2014-03-05 42 views
0

我在Javascript中編寫了一個類Student。在MongoDB中傳入Javascript類MapReduce範圍將由地圖使用

function Student(info) { 
    this.getName(info); 
    this.getAge(info); 
} 

Student.prototype.getName = function(info) { 
    this.name = info.name; 
}; 

Student.prototype.getAge = function(info) { 
    this.age = info.age; 
}; 

現在,我需要這個類裏面map函數的mongoDB mapReduce框架。即,

var mapFunction = function() { 
    var student = new Student(this); 
    emit(student.name, student.age); 
}; 

此功能圖無權訪問此功能以外定義的學生。因此,我需要通過mapReduce的範圍來傳遞這個類。

var scopeVar = { Student: Student}; 
db.collection.mapReduce(
    mapFunction, 
    { 
    scope: scopeVar, 
    out: { merge: 'testCollection'} 
    } 
); 

但是,事實證明,在內部地圖中,我們有Student定義,但Student.prototype是空的。爲了驗證這一點,我寫了替代mapTest,

var mapTest = function() { 
    emit(Student, Student.prototype); 
}; 

var scopeVar = { Student: Student}; 
db.collection.mapReduce(
    mapTest, 
    { 
    scope: scopeVar, 
    out: { merge: 'testCollection'} 
    } 
); 

在db.testCollection,人們可以看到,輸出文檔看起來像這樣

{_id: function Student(info) { 
    this.getName(info); 
    this.getAge(info); 
}, 
value: {} 
} 

因此,似乎在某種程度上範圍不復制的原型物體。

如果想將輔助函數定義爲類的原型函數,那麼如何將它傳遞給mapReduce的作用域呢?

+0

爲什麼不簡單地做一些簡單的事情並在map函數中包含源代碼? – WiredPrairie

+0

我還建議您考慮儘可能快速和簡單地保持代碼。是否需要一個完整的對象? – WiredPrairie

+0

我同意這是簡單和最簡單的解決方案。但是,有理由反對。如果這個類與幾個原型函數非常複雜,那麼最好將它們分開以進行代碼管理。 – user3385768

回答

0

我的假設是MongoDB在C中實現,CLI或執行引擎讀取代碼並將其提交給V8Engine。因此,Prototype的解釋上下文不會被CLI感知,因此不會被提交給V8引擎。範圍參數增強了參數機制,但並沒有像預期的那樣給出完整的動態性質。在內部,mongodb必須創建具有給定範圍的另一個函數。爲了實現你提到的,我會嘗試這樣的:

這應該工作。

var scopeVar = { Student: Student, StudentPrototype: Student.prototype }; 

var mapFunction = function() { 
Student.prototype = StudentPrototype; 
var student = new Student(this); 
    emit(student.name, student.age); 
}; 
+0

感謝user3385768,編輯了我的示例代碼 – user640554

0

以上答案在方法中是正確的。正確的答案如下。

var scopeVar = { Student: Student, StudentPrototype: Student.prototype }; 

var mapFunction = function() { 
    Student.prototype = StudentPrototype; 
    var student = new Student(this); 
    emit(student.name, student.age); 
};