Bas*_*wer 17 javascript mongoose mongodb node.js mongodb-query
是否可以在Mongo中插入条件;
//Pseudo code
Bulk Insert Item :
If Key exists
Skip, don't throw error
If key does not exist
Add item
Run Code Online (Sandbox Code Playgroud)
如果我执行单个插入,它可能会在集合中返回错误或插入,但是可以批量生成吗?
Bla*_*ven 23
根据你想要处理的事情,你有两个真正的选择:
如果密钥数据存在,则使用MongoDB的upsert功能实质上"查找".如果没有,那么您只传入数据,$setOnInsert并且不会触及任何其他内容.
在Bulk中使用"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();
}
);
Run Code Online (Sandbox Code Playgroud)
请注意,当前驱动程序中的"已更改操作"是结果响应.execute() 将返回要抛出的错误对象,其中先前版本未执行"未订购"操作.
这使得您的代码必须永远不依赖于err单独返回的代码,并且您应该将返回的代码result用于完整的错误分类.
尽管如此,当无序时,无论发生多少错误,批次都会一直持续到结束.不是错误的事情将照常进行.
这实际上归结为"序列重要".如果是这样,那么您需要"有序"操作,并且您只能通过使用"upserts"来避免重复键.否则使用"无序",但要注意错误返回以及它们实际意味着什么.
此外,当使用.collection从基本驱动程序获取底层集合对象以启用"批量"操作时,请始终确保始终首先调用"某些"mongoose方法.
如果没有这个,就没有保证使用本机驱动程序方法连接到数据库,因为它是为mongoose方法处理的,因此操作将因无连接而失败.
首先"触发"mongoose方法的替代方法是将应用程序逻辑包装在事件监听器中以进行连接:
mongoose.connection.on("open",function(err) {
// app logic in here
})
Run Code Online (Sandbox Code Playgroud)
使用setOnInsert
db.collection('collection').updateOne(
{ _id: data._id },
{ $setOnInsert: { ...data } },
{ upsert: true },
)
Run Code Online (Sandbox Code Playgroud)
MongoDB 版本 4.4
https://docs.mongodb.com/manual/reference/operator/update/setOnInsert/
小智 5
正如已经说过的,“可以通过插入设置为true 的update命令upsert来实现”。使用3.x node.js驱动程序的方法如下:
let ops = [];
ops.push({ updateOne: { filter: {key:"value1"}, update: {} }, { upsert:true } });
ops.push({ updateOne: { filter: {key:"value2"}, update: { $set:{/*...*/} } }, { upsert:true } });
ops.push({ updateOne: { filter: {key:"value3"}, update: { { $setOnInsert:{/*...*/} } } }, { upsert:true } });
// < add more ops here >
await db.collection("my-collection").bulkWrite(ops, {ordered:false});
Run Code Online (Sandbox Code Playgroud)
如果filter返回的结果为零,则将使用过滤条件和$set更新(如果有)来创建一个新文档。如果使用$setOnInsert,则更新仅适用于新文档。
发布此示例,因为它对我的情况非常有用。文档中有关db.collection.bulkWrite的更多信息。
| 归档时间: |
|
| 查看次数: |
19370 次 |
| 最近记录: |