몽구스 (mongodb) 배치 삽입물?
Mongoose v3.6 + 는 이제 배치 삽입을 지원 합니까 ? 나는 몇 분 동안 검색했지만이 쿼리와 일치하는 것은 몇 살이었고 그 대답은 분명했습니다.
편집하다:
나중에 참조 할 수있는 대답은 Model.create()
입니다. create()
배열을 첫 번째 인수로 받아들이므로 문서를 배열로 삽입하도록 전달할 수 있습니다.
Model.create () 문서를 참조하십시오
Model.create () vs. Model.collection.insert () : 더 빠른 접근법
Model.create()
매우 큰 부피를 다루는 경우 인서트를 수행하는 나쁜 방법입니다. 그것은 될 것입니다 매우 느립니다 . 이 경우 훨씬 더 나은Model.collection.insert
성능 을 사용해야합니다 . 벌크 크기에 따라 충돌이 발생합니다! 백만 장의 문서로 시험해 보았습니다. 사용 그것은 단지 몇 초 걸렸습니다.Model.create()
Model.collection.insert
Model.collection.insert(docs, options, callback)
docs
삽입 할 문서의 배열입니다.options
선택적 구성 개체입니다 . 문서를 참조하십시오 .callback(err, docs)
모든 문서가 저장되거나 오류가 발생한 후 호출됩니다. 성공하면 문서는 지속되는 문서의 배열입니다.
Mongoose의 저자가 여기 에서 지적한 것처럼 ,이 방법은 모든 검증 절차를 우회하고 Mongo 드라이버에 직접 액세스합니다. 많은 양의 데이터를 처리하기 때문에 수행해야 할 절충점입니다. 그렇지 않으면 데이터베이스에 전혀 삽입 할 수 없습니다 (여기서는 수십만 개의 문서를 이야기하고 있음을 기억하십시오).
간단한 예
var Potato = mongoose.model('Potato', PotatoSchema);
var potatoBag = [/* a humongous amount of potato objects */];
Potato.collection.insert(potatoBag, onInsert);
function onInsert(err, docs) {
if (err) {
// TODO: handle error
} else {
console.info('%d potatoes were successfully stored.', docs.length);
}
}
2019-06-22 업데이트 : insert()
여전히 잘 사용할 수는 있지만 더 이상 사용되지 않습니다 insertMany()
. 매개 변수는 정확히 동일하므로 드롭 인 대체로 사용할 수 있으며 모든 것이 잘 작동합니다 (반환 값이 약간 다르지만 어쨌든 사용하지 않을 것입니다).
참고
몽구스 4.4.0은 이제 대량 삽입을 지원합니다
Mongoose 4.4.0은 model 메소드를 사용하여 --true-- 대량 삽입을 도입했습니다 .insertMany()
. 루핑 .create()
하거나 어레이를 제공하는 것 보다 훨씬 빠릅니다 .
용법:
var rawDocuments = [/* ... */];
Book.insertMany(rawDocuments)
.then(function(mongooseDocuments) {
/* ... */
})
.catch(function(err) {
/* Error handling */
});
또는
Book.insertMany(rawDocuments, function (err, mongooseDocuments) { /* Your callback function... */ });
당신은 그것을 추적 할 수 있습니다 :
- https://github.com/Automattic/mongoose/issues/723
- https://github.com/Automattic/mongoose/blob/1887e72694829b62f4e3547283783cebbe66b46b/lib/model.js#L1774
실제로 몽구스의 "만들기"방법을 사용할 수 있으며, 문서 배열을 포함 할 수 있습니다.이 예를 참조하십시오.
Candy.create({ candy: 'jelly bean' }, { candy: 'snickers' }, function (err, jellybean, snickers) {
});
콜백 함수는 삽입 된 문서를 포함합니다. 삽입해야 할 항목 수 (위와 같이 수정 된 인수 길이)를 항상 알지 못하므로 반복 할 수 있습니다.
var insertedDocs = [];
for (var i=1; i<arguments.length; ++i) {
insertedDocs.push(arguments[i]);
}
업데이트 : 더 나은 솔루션
A better solution would to use Candy.collection.insert()
instead of Candy.create()
- used in the example above - because it's faster (create()
is calling Model.save()
on each item so it's slower).
See the Mongo documentation for more information: http://docs.mongodb.org/manual/reference/method/db.collection.insert/
(thanks to arcseldon for pointing this out)
You can perform bulk insert using mongoDB shell using inserting the values in an array.
db.collection.insert([{values},{values},{values},{values}]);
You can perform bulk insert using mongoose, as the highest score answer. But the example cannot work, it should be:
/* a humongous amount of potatos */
var potatoBag = [{name:'potato1'}, {name:'potato2'}];
var Potato = mongoose.model('Potato', PotatoSchema);
Potato.collection.insert(potatoBag, onInsert);
function onInsert(err, docs) {
if (err) {
// TODO: handle error
} else {
console.info('%d potatoes were successfully stored.', docs.length);
}
}
Don't use a schema instance for the bulk insert, you should use a plain map object.
It seems that using mongoose there is a limit of more than 1000 documents, when using
Potato.collection.insert(potatoBag, onInsert);
You can use:
var bulk = Model.collection.initializeOrderedBulkOp();
async.each(users, function (user, callback) {
bulk.insert(hash);
}, function (err) {
var bulkStart = Date.now();
bulk.execute(function(err, res){
if (err) console.log (" gameResult.js > err " , err);
console.log (" gameResult.js > BULK TIME " , Date.now() - bulkStart );
console.log (" gameResult.js > BULK INSERT " , res.nInserted)
});
});
But this is almost twice as fast when testing with 10000 documents:
function fastInsert(arrOfResults) {
var startTime = Date.now();
var count = 0;
var c = Math.round( arrOfResults.length / 990);
var fakeArr = [];
fakeArr.length = c;
var docsSaved = 0
async.each(fakeArr, function (item, callback) {
var sliced = arrOfResults.slice(count, count+999);
sliced.length)
count = count +999;
if(sliced.length != 0 ){
GameResultModel.collection.insert(sliced, function (err, docs) {
docsSaved += docs.ops.length
callback();
});
}else {
callback()
}
}, function (err) {
console.log (" gameResult.js > BULK INSERT AMOUNT: ", arrOfResults.length, "docsSaved " , docsSaved, " DIFF TIME:",Date.now() - startTime);
});
}
Here are both way of saving data with insertMany and save
1) Mongoose save array of documents with insertMany
in bulk
/* write mongoose schema model and export this */
var Potato = mongoose.model('Potato', PotatoSchema);
/* write this api in routes directory */
router.post('/addDocuments', function (req, res) {
const data = [/* array of object which data need to save in db */];
Potato.insertMany(data)
.then((result) => {
console.log("result ", result);
res.status(200).json({'success': 'new documents added!', 'data': result});
})
.catch(err => {
console.error("error ", err);
res.status(400).json({err});
});
})
2) Mongoose save array of documents with .save()
These documents will save parallel.
/* write mongoose schema model and export this */
var Potato = mongoose.model('Potato', PotatoSchema);
/* write this api in routes directory */
router.post('/addDocuments', function (req, res) {
const saveData = []
const data = [/* array of object which data need to save in db */];
data.map((i) => {
console.log(i)
var potato = new Potato(data[i])
potato.save()
.then((result) => {
console.log(result)
saveData.push(result)
if (saveData.length === data.length) {
res.status(200).json({'success': 'new documents added!', 'data': saveData});
}
})
.catch((err) => {
console.error(err)
res.status(500).json({err});
})
})
})
I used async-forEach(link for async-forEach npm package documentation) to achieve the same.
My code snippet is as below.I am getting the documents in the req.body.
var forEach = require('async-foreach').forEach;
exports.save_Ctrl = function (req, res) {
// var l=req.body;
// console.log("length:",l.length);
forEach(req.body, function(item, index, object,err) {
console.log(req.body[index]);
var post = new saveObj(req.body[index]);
//save model to MongoDB
post.save(function (err) {
if (err) {
console.log('error saving :' + err.message);
return err;
}
else {
console.log("Post saved");
}
});
});
}
Sharing working and relevant code from our project:
//documentsArray is the list of sampleCollection objects
sampleCollection.insertMany(documentsArray)
.then((res) => {
console.log("insert sampleCollection result ", res);
})
.catch(err => {
console.log("bulk insert sampleCollection error ", err);
});
참고URL : https://stackoverflow.com/questions/16726330/mongoose-mongodb-batch-insert
'IT story' 카테고리의 다른 글
CMakeLists.txt에 Boost 라이브러리를 어떻게 추가합니까? (0) | 2020.08.05 |
---|---|
Textview에서 문자 간격을 변경하는 방법은 무엇입니까? (0) | 2020.08.04 |
연결할 수없는 코드이지만 예외가있는 경우 (0) | 2020.08.04 |
Node.js는 everyauth와 함께 사용할 환경 별 구성 설정 (0) | 2020.08.04 |
Angular 2의 패시브 링크- (0) | 2020.08.04 |