( [email protected] 、 [email protected] )
TL; DR
await GasStation.collection.bulkWrite([ // <<==== use the model name
{
'updateOne': {
'filter': { 'id': '<some id>' },
'update': { '$set': { /* properties to update */ } },
'upsert': true, // <<==== upsert in every document
}
},
/* other operations here... */
]);
長い話:
MongooseAPIの貧弱なドキュメント
に苦労した後 、バルクアップサートを解決しました updateOne:{}
を微調整する bulkWrite()
での操作 メソッド。
考慮すべき文書化されていない事項のいくつか:
// suppose:
var GasStation = mongoose.model('gasstation', gasStationsSchema);
var bulkOps = [ ];
// for ( ... each gasStation to upsert ...) {
let gasStation = { country:'a', localId:'b', xyz:'c' };
// [populate gasStation as needed]
// Each document should look like this: (note the 'upsert': true)
let upsertDoc = {
'updateOne': {
'filter': { 'country': gasStation.country, 'localId': gasStation.localId },
'update': gasStation,
'upsert': true
}};
bulkOps.push(upsertDoc);
// end for loop
// now bulkWrite (note the use of 'Model.collection')
GasStation.collection.bulkWrite(bulkOps)
.then( bulkWriteOpResult => {
console.log('BULK update OK');
console.log(JSON.stringify(bulkWriteOpResult, null, 2));
})
.catch( err => {
console.log('BULK update error');
console.log(JSON.stringify(err, null, 2));
});
ここで重要な2つのことは、不完全なAPIドキュメントの問題です(少なくとも執筆時点では):
-
'upsert': true
各ドキュメント内 。これは、多くの場合 node-mongodb-native を参照するMongooseAPI()には記載されていません。 運転者。このドライバーのupdateOne を見る 、 'options':{'upsert': true}
を追加することを考えることができます 、しかし、いいえ...それはしません。また、両方のケースをbulkWrite(,[options],)
に追加しようとしました 引数、効果もありません。 -
GasStation.collection.bulkWrite()
。 マングースbulkWrite()メソッドModel.bulkWrite()
と呼ばれるべきだと主張している (この場合、GasStation.bulkWrite()
)、これによりMongoError: Unknown modifier: $__
がトリガーされます 。したがって、Model.collection.bulkWrite()
使用する必要があります。
さらに、注意:
-
$set
を使用する必要はありませんupdateOne.update
のmongo演算子 フィールド、マングースはアップサートの場合にそれを処理するため(例のbulkWrite()コメントを参照 。 - スキーマ内の一意のインデックス(upsertが正しく機能するために必要)は次のように定義されていることに注意してください:
gasStationsSchema.index({ country: 1, localId: 1 }, { unique: true });
お役に立てば幸いです。
==>編集:(マングース5?)
@JustinSmithが気付いたように、$set
Mongooseによって追加された演算子はもう機能していないようです。多分それはマングース5のせいですか?
いずれにせよ、$set
を使用します 明示的に行う必要があります:
'update': { '$set': gasStation },