ここでは、処理方法に応じて2つの実際の選択肢があります。
-
upsert を使用します キーデータが存在する場合、本質的に「ルックアップ」するMongoDBの機能。そうでない場合は、データを
$setOnInsert
そしてそれは他に何も触れません。 -
「UnOrdered」操作を一括で使用します。エラーが返された場合でも、更新のバッチ全体が続行されますが、エラーレポートはそれだけであり、エラーでないものはすべてコミットされます。
全体の例:
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
var testSchema = new Schema({
"_id": Number,
"name": String
},{ "_id": false });
var Test = mongoose.model('Test',testSchema,'test');
mongoose.connect('mongodb://localhost/test');
var data = [
{ "_id": 1, "name": "One" },
{ "_id": 1, "name": "Another" },
{ "_id": 2, "name": "Two" }
];
async.series(
[
// Start fresh
function(callback) {
Test.remove({},callback);
},
// Ordered will fail on error. Upserts never fail!
function(callback) {
var bulk = Test.collection.initializeOrderedBulkOp();
data.forEach(function(item) {
bulk.find({ "_id": item._id }).upsert().updateOne({
"$setOnInsert": { "name": item.name }
});
});
bulk.execute(callback);
},
// All as expected
function(callback) {
Test.find().exec(function(err,docs) {
console.log(docs)
callback(err);
});
},
// Start again
function(callback) {
Test.remove({},callback);
},
// Unordered will just continue on error and record an error
function(callback) {
var bulk = Test.collection.initializeUnorderedBulkOp();
data.forEach(function(item) {
bulk.insert(item);
});
bulk.execute(function(err,result) {
callback(); // so what! Could not care about errors
});
},
// Still processed the whole batch
function(callback) {
Test.find().exec(function(err,docs) {
console.log(docs)
callback(err);
});
}
],
function(err) {
if (err) throw err;
mongoose.disconnect();
}
);
現在のドライバーの「変更されたアクション」は、.execute()
での結果の応答であることに注意してください。 します 以前のリリースでは「順序付けされていない」操作ではスローされなかった、スローされるエラーオブジェクトを返します。
これにより、コードがerr
に依存しないことが不可欠になります。 単独で返され、返されたresult
を入力する必要があります 代わりに、エラーを完全に分類します。
それでも、順序付けされていない場合、エラーがいくつ発生しても、バッチは最後まで続行されます。エラーではないものは通常どおりコミットされます。
これは本当に「シーケンスが重要」に帰着します。その場合、「注文済み」操作が必要であり、「アップサート」を使用することによってのみキーの重複を回避できます。それ以外の場合は「順序なし」を使用しますが、エラーの戻り値と実際の意味に注意してください。
また、.collection
を使用する場合 ベースドライバから基になるコレクションオブジェクトを取得して「バルク」操作を有効にするには、常にいずれかの「一部の」マングースメソッドが常に最初に呼び出されていることを確認してください。
これがないと、マングースメソッドで処理されるため、ネイティブドライバーメソッドを使用したデータベースへの接続が保証されないため、接続がないために操作が失敗します。
最初にマングースメソッドを「起動」する代わりに、接続のイベントリスナーでアプリロジックをラップすることもできます。
mongoose.connection.on("open",function(err) {
// app logic in here
})