Mongoose와 함께 대량 상승을 시도하고 있습니다.가장 깨끗한 방법은 무엇입니까?
first_name, last_name 및 age의 세 가지 필드가 포함된 문서를 보관하는 컬렉션이 있습니다.Mongoose에서 대량 업셋을 수행하는 데 사용할 수 있는 쿼리를 찾고 있습니다.내 앱은 때때로 동일한 세 개의 필드를 가진 새로운 객체 배열을 수신합니다.문서에 이름과 성이 이미 존재하는지, 존재하는지, 존재하는지 여부를 쿼리에서 확인하고, 다른 경우 기간을 업데이트합니다.그렇지 않은 경우, 이름과 성이 없는 경우, 새 문서를 삽입합니다.
현재, 저는 가져오기만 하고 있으며, 이 비정상적인 작품에 대한 논리를 아직 구축하지 못했습니다.
app.post('/users/import', function(req, res) {
let data = req.body;
let dataArray = [];
data.forEach(datum => {
dataArray.push({
first: datum.first,
last: datum.last,
age: datum.age
})
})
User.insertMany(dataArray, answer => {
console.log(`Data Inserted:`,answer)
})
`
제 사용자 모델은 다음과 같습니다.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
first: String,
last: String,
age: Number,
created_at: { type: Date, default: Date.now }
});
var User = mongoose.model('User', userSchema);
module.exports = User;
(mongoose@4.9.1, mongodb@3.4.2)
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... */
]);
긴 이야기:
Mongoose API 문서 불량으로 어려움을 겪은 후 대량 업셋 수정을 해결했습니다.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));
});
여기서 두 가지 핵심 사항은 불완전한 API 문서 문제입니다(적어도 작성 시점에서는).
'upsert': true
각 서류에이 문제는 Mongoose API()에는 설명되어 있지 않습니다. Mongoose API는 종종 노드-mongodb 네이티브 드라이버를 가리킵니다.업데이트를 보면 이 드라이버에서 하나를 추가할 수 있습니다.'options':{'upsert': true}
하지만, 아니...그것으로는 안 됩니다.저는 또한 두 가지 사례를 추가하려고 했습니다.bulkWrite(,[options],)
인수도 효과가 없습니다.GasStation.collection.bulkWrite()
Mongoose bulkWrite() 메서드가 호출되어야 한다고 주장하지만Model.bulkWrite()
(이 경우에는,GasStation.bulkWrite()
), 트리거합니다.MongoError: Unknown modifier: $__
.그렇게,Model.collection.bulkWrite()
사용해야 합니다.
추가로, 참고:
사용할 필요가 없습니다.$set
의 몽고 연산자updateOne.update
필드, mongoose는 업버트 시 처리하기 때문입니다(예: bulkWrite() 주석 참조).- 스키마의 고유 인덱스(업그레이드를 위해 필요함)는 다음과 같이 정의됩니다.
gasStationsSchema.index({ country: 1, localId: 1 }, { unique: true });
도움이 되길 바랍니다.
==> EDIT : (몽구스5?)
@Justin Smith가 주목했듯이,$set
Mongoose가 추가한 연산자는 더 이상 작동하지 않는 것 같습니다.Mongoose 5 때문인가요?
어떤 경우에도, 사용$set
다음을 수행해야 합니다.
'update': { '$set': gasStation },
@maganap 감사합니다.저는 그/그녀의 답변을 이용하여 아래와 같은 간결한 접근법에 도달했습니다.
await Model.bulkWrite(docs.map(doc => ({
updateOne: {
filter: {id: doc.id},
update: doc,
upsert: true,
}
})))
또는 자세한 내용:
const bulkOps = docs.map(doc => ({
updateOne: {
filter: {id: doc.id},
update: doc,
upsert: true,
}
}))
Model.bulkWrite(bulkOps)
.then(console.log.bind(console, 'BULK update OK:', bulkWriteOpResult))
.catch(console.error.bind(console, 'BULK update error:'))
Mongoose용으로 정적을 노출하는 작은 플러그인을 릴리스했습니다.upsertMany
약속 인터페이스를 사용하여 대량 업버트 작업을 수행하는 방법입니다.이를 통해 스키마 유효성 검사 등을 유지하면서 Mongoose를 사용하여 대량 업그레이드를 수행하는 매우 깨끗한 방법을 제공할 수 있습니다.
MyModel.upsertMany(items, ['matchField', 'other.nestedMatchField']);
이 플러그인은 npm 또는 Github에서 찾을 수 있습니다.
https://github.com/meanie/mongoose-upsert-many https://www.npmjs.com/package/ @mongoose-upert-many
위의 @magnap 솔루션을 사용해보니 단순히 업데이트하고 싶었던 기존 문서를 덮어쓰는 것이었습니다.에서 설정한 updates.updateOne
필드를 에 지정된 로 대체하는 이었습니다..update
.
저는 결국 사용해야 했습니다.$set
이 문제를 해결하기 위한 업데이트 방법입니다.과 같이 표시되었습니다.
const { ObjectId } = require('mongodb');
exports.bulkUpsert = (req, res, next) => {
const { updates } = req.body;
const bulkOps = updates.map(update => ({
updateOne: {
filter: { _id: ObjectId(update.id) },
// Where field is the field you want to update
update: { $set: { field: update.field } },
upsert: true
}
}));
// where Model is the name of your model
return Model.collection
.bulkWrite(bulkOps)
.then(results => res.json(results))
.catch(err => next(err));
};
이는 Mongoose 5.1.2와 함께 작동합니다.
사용할 수 있습니다.array.map
대신에 사용합니다.for
const result = await Model.bulkWrite(
documents.map(document => {
document = {
...document,
...{
last_update: Date.now(),
foo: 'bar'
}
}
return {
updateOne: {
filter: { document_id: document.document_id }, //filter for each item
update: {
$set: document,//update whole document
$inc: { version: 1 }//increase version + 1
},
upsert: true //upsert document
}
}
}
));
여기 제 답변이 도움이 되길 바랍니다.비동기식으로 e커머스 도메인에 대한 대량 업버트를 처리합니다.
공식 솔루션 찾기: https://docs.mongodb.com/manual/reference/method/Bulk.find.upsert/
그리고 몽구스도 같은 사슬을 지지합니다.
Bulk.find(<query>).upsert().update(<update>);
Bulk.find(<query>).upsert().updateOne(<update>);
Bulk.find(<query>).upsert().replaceOne(<replacement>);
작동 테스트:
BulkWriteResult {
result:
{ ok: 1,
writeErrors: [],
writeConcernErrors: [],
insertedIds: [],
nInserted: 0,
nUpserted: 1,
nMatched: 4186,
nModified: 0,
nRemoved: 0,
upserted: [ [Object] ] } }
이것을 확인하세요. 이것이 당신에게 충분히 도움이 되기를 바랍니다. 링크
제 생각에 당신은 찾고 있는 것 같습니다.
당신은 이것을 사용할 수 있습니다.
bulk = db.yourCollection.initializeUnorderedBulkOp();
for (<your for statement>) {
bulk.find({ID: <your id>, HASH: <your hash>}).upsert().update({<your update fields>});
}
bulk.execute(<your callback>)
- 문서를 찾으면 {}을(를) 사용하여 해당 문서를 업데이트합니다.
- 그렇지 않으면 새 문서가 만들어집니다.
언급URL : https://stackoverflow.com/questions/39988848/trying-to-do-a-bulk-upsert-with-mongoose-whats-the-cleanest-way-to-do-this
'programing' 카테고리의 다른 글
Git Submodule HEAD가 마스터에서 분리되는 이유는 무엇입니까? (0) | 2023.07.17 |
---|---|
C/C++ 컴파일러가 컴파일 시 배열의 크기를 알아야 하는 이유는 무엇입니까? (0) | 2023.07.17 |
Oracle에서 열이 empty_clob()인지 테스트하려면 어떻게 해야 합니까? (0) | 2023.07.17 |
키 속성이 유형 스크립트에서 이벤트 유형의 일부로 인식되지 않는 이유는 무엇입니까? (0) | 2023.07.17 |
"Fire and Forget" python 비동기/대기 (0) | 2023.07.17 |