我有一個使用mongoDB的node.js應用程序,我有一個函數用於刪除集合中的所有文檔,然後重新填充我的數據庫中的集合一些樣本文件。mongoDB getLastError()javascript和node.js不工作
當我編寫新功能時,我曾用它在已知數據中測試過我的應用程序。
我碰到的問題是,如果我在我所有的集合上調用drop(),然後調用一些插入來重新填充,有時我會有比我期望插入數據庫的記錄更少的記錄,有時整個集合將會失蹤。我的計數會檢查所有插入的符合預期金額的#個記錄,但是即使它已插入,整個集合也可能會丟失。
我只能假設,因爲它只發生大約50%的時間,或許某種程度上插入開始在drop()完成之前插入,然後drop()由於其正在運行的異步而刪除插入的文檔。
我在所有插入/更新命令中使用{safe:true},但db.collection.drop()不帶任何參數,似乎無法指定安全選項。
所以我試圖在drop()之後使用db.getLastError()來阻塞插入,直到刪除完成。
使用db.getLastError()或db.getlasterror()拋出一個錯誤: 類型錯誤:對象#< Db的>沒有方法 'GetLastError函數'
簡化呼叫到GetLastError函數:
var mongo = require("mongodb");
var db_conn = new mongo.Db(dbName, new mongo.Server(host, port, { auto_reconnect: true }), {});
db_conn.open(function(err, db) {
if(!err) {
console.log("Database connection: \033[32mopen\033[0m");
} else {
console.log("Database connection: \033[31mfailed\033[0m");
}
});
db_conn.getLastError();
this.db_conn = db_conn;
this.users = db_conn.collection("users");
this.companies = db_conn.collection("companies");
this.suppliers = db_conn.collection("suppliers");
我已經在mongodb模塊版本1.1.4和1.1.7上試過了,只是出現錯誤。
我使用的是錯誤的引用嗎?我在JavaScript中的代碼示例中找不到任何關於stackoverflow或web上的getlasterror。
如果有更好的方法來做到這一點,我全部耳朵。
JS文檔:http://docs.mongodb.org/manual/reference/javascript/#db.getLastError
蒙戈文檔:http://www.mongodb.org/display/DOCS/getLastError+Command
---- UPDATE 2012年9月22日
使用下面的回答,我能夠調試了一下問題的根源是什麼,它的如我所料。使用5個打開連接的默認連接池,墨滴會隨機發射,然後隨即插入。根據它們發送的順序以及它們各自到達的池,如果一個子快速完成,然後在該子集的刪除完成之前快速插入,它將在稍後刪除插入的記錄。
我的修補程序是在drop()命令的回調中將所有的下降包裝在一個鏈接序列中,以便每次下降發生在上一個下拉的回調被觸發後,然後在最後調用一個回調所有的插入。這很麻煩,但我已經使用20個簡單插入的基本記錄集和100,000個記錄的加載測試測試了初始化的b函數現在約25次。沒有失敗。
時間會告訴,但這個.lastError()答案工作來解決這個問題。
---- UPDATE 2012年9月30日
我想回響應,以確保它的實際工作之前測試這一個星期左右。我已經在上週運行了我的初始化腳本約100次,包括26個記錄的基本集合和100,000個記錄全部被批量插入。我還沒有看到它現在使用我的新代碼失敗了。
代碼我用丟棄集合:(我有我的原型功能操作使用一個數據庫處理器對象)
DatabaseHandler.prototype.dropAll = function(callback, callbackArg) {
// drop all the documents
var that = this;
var finished = callback || function() { };
var finishedArg = callbackArg;
this.companies.drop(function(err, reply) {
if(reply) {
console.log("[db] Companies collection dropped");
} else {
console.log("\033[31m[Error]\033[0m Companies collection failed to drop");
}
// drop all the user documents
that.users.drop(function(err, reply) {
if(reply) {
console.log("[db] Users collection dropped");
} else {
console.log("\033[31m[Error]\033[0m Users collection failed to drop");
}
// drop all the course documents
that.courses.drop(function(err, reply) {
if(reply) {
console.log("[db] Courses collection dropped");
} else {
console.log("\033[31m[Error]\033[0m Courses collection failed to drop");
}
// drop all the course purchase documents
that.course_purchases.drop(function(err, reply) {
if(reply) {
console.log("[db] Course purchases collection dropped");
} else {
console.log("\033[31m[Error]\033[0m Course purchases collection failed to drop");
}
console.log("Dropped all documents and collections");
return finished(finishedArg);
});
});
});
});
};
然後我有一個初始化函數,它的參數來指定,如果我想額外負擔測試數據初始化(addloadtestdata)。如果我指定dropdata,它將調用dropAll並將初始化函數用於回調。所以當放置完成時,它會調用initialize回調,並在文檔完成刪除後纔開始重新添加文檔。 我還有一個小計數功能,可以在完成插入操作後檢查插入了多少個文檔,以驗證插入了正確的數字,並且沒有錯過。這可能是我添加了所有最好的功能,使我每次初始化時間,我可以看到,如果插入的文件的確切數字是正確的,或者如果我失去了甚至1.
function initialize(doLoadtest){
// do work here
}
// drop all collections and documents
if(dropdata) {
// drop all the data first then call the initialize as a callback function when completed dropping
Database.dropAll(initialize, includeLoadtestData);
} else {
initialize(includeLoadtestData);
}
希望幫助
我有一個類似的問題,當我跑我的摩卡測試。這絕對是一個時間問題。我也設置了'{safe:true}',但似乎沒有太大區別。我放了1秒的setTimeout來解決這個問題(只在測試中)。現在它工作的時間有95%。 – c0deNinja
你可以發佈你最終使用的代碼嗎? – c0deNinja
上面加了代碼示例 – Dhodgin