MongoDB에서 삭제 시 참조 개체 자동 제거
다음과 같은 스키마가 있다고 가정합니다.
var Person = new Schema({
name: String
});
var Assignment = new Schema({
name: String,
person: ObjectID
});
사용자를 삭제하더라도 존재하지 않는 사용자를 참조하는 고아 할당이 남아 데이터베이스에 불필요한 혼란이 발생할 수 있습니다.
사용자가 삭제될 때 해당 사용자에 대한 모든 참조도 삭제되도록 하는 간단한 방법이 있습니까?
사용자가 직접 추가할 수 있습니다.'remove'
Mongoose 미들웨어는Person
스키마를 사용하여 해당 사용자를 참조하는 다른 모든 문서에서 제거합니다.당신의 미들웨어 기능에서,this
그것은Person
삭제할 문서입니다.
Person.pre('remove', function(next) {
// Remove all the assignment docs that reference the removed person.
this.model('Assignment').remove({ person: this._id }, next);
});
"단순"이 "기본 제공"을 의미하는 경우 "아니오"입니다.MongoDB는 결국 관계형 데이터베이스가 아닙니다.독자적인 세척 메커니즘을 구현해야 합니다.
그remove()
메서드가 더 이상 사용되지 않습니다.
따라서 Mongoose 미들웨어에서 '제거'를 사용하는 것은 더 이상 모범 사례가 아닙니다.
Mongoose는 및 에 대한 후크를 제공하는 업데이트를 만들었습니다. 대신에 후크를 만들 수 있습니다.
Person.pre('deleteMany', function(next) {
var person = this;
person.model('Assignment').deleteOne({ person: person._id }, next);
});
프리훅을 찾는 사람이 있을 경우에 대비해서.deleteOne
그리고.deleteMany
기능 이것은 저에게 맞는 솔루션입니다.
const mongoose = require('mongoose');
...
const PersonSchema = new mongoose.Schema({
name: {type: String},
assignments: [{type: mongoose.Schema.Types.ObjectId, ref: 'Assignment'}]
});
mongoose.model('Person', PersonSchema);
....
const AssignmentSchema = new mongoose.Schema({
name: {type: String},
person: {type: mongoose.Schema.Types.ObjectId, ref: 'Person'}
});
mongoose.model('Assignment', AssignmentSchema)
...
PersonSchema.pre('deleteOne', function (next) {
const personId = this.getQuery()["_id"];
mongoose.model("Assignment").deleteMany({'person': personId}, function (err, result) {
if (err) {
console.log(`[error] ${err}`);
next(err);
} else {
console.log('success');
next();
}
});
});
호출 중deleteOne
서비스 중인 기능:
try {
const deleted = await Person.deleteOne({_id: id});
} catch(e) {
console.error(`[error] ${e}`);
throw Error('Error occurred while deleting Person');
}
참조된 사용자 문서가 삭제된 경우에도 문서를 그대로 둘 수 있습니다.Mongodb는 존재하지 않는 문서를 가리키는 참조를 지웁니다. 이는 참조된 문서를 삭제한 직후에 발생하지 않습니다.대신 문서에 대한 작업(예: 업데이트)을 수행할 때입니다.또한 참조가 지워지기 전에 데이터베이스를 쿼리하더라도 null 값 대신 반환이 비어 있습니다.
두 번째 옵션은 아래와 같이 $unset 연산자를 사용하는 것입니다.
{ $unset: { person: "<person id>"} }
조회에서 참조 값을 나타내기 위해 개인 ID를 사용합니다.
소프트 삭제를 사용할 수 있습니다.사용자 컬렉션에서 사용자를 삭제하지 않고 isDelete 부울 플래그를 true로 사용합니다.
사용하다$pull
여러분이 이런 구조를 가지고 있다고 가정해 보겠습니다.
재료 컬렉션:
_id: ObjectId('63dd23c633c17a718c4c5db7')
item: "Item 1"
user: ObjectID('63de669153bc12ecb9081b9e')
사용자 컬렉션:
_id: ObjectId('63de669153bc12ecb9081b9e')
stuff: array[ObjectId('63dd23c633c17a718c4c5db7'), ObjectId('63de3a69715ec134e161b0ea')]
그런 다음 물건을 제거한 후:
const stuff = Stuff.findById(req.params.id)
const user = User.findById(req.params.id)
await stuff.remove()
// here you can use $pull to update
await user.updateOne({
$pull: {
stuff: stuff.id
}
})
삭제해야 하는 모델을 호출하고 다음과 같이 해당 문서를 삭제할 수 있습니다.
PS: 이 답변은 질문 스키마에만 해당되지 않습니다.
const Profiles = require('./profile');
userModal.pre('deleteOne', function (next) {
const userId = this.getQuery()['_id'];
try {
Profiles.deleteOne({ user: userId }, next);
} catch (err) {
next(err);
}
});
사용자 삭제 경로에서
exports.deleteParticularUser = async (req, res, next) => {
try {
await User.deleteOne({
_id: req.params.id,
});
return res.status(200).json('user deleted');
} catch (error) {
console.log(`error`, error);
return next(error);
}
};
언급URL : https://stackoverflow.com/questions/11904159/automatically-remove-referencing-objects-on-deletion-in-mongodb
'programing' 카테고리의 다른 글
선택한 요소의 외부 HTML 가져오기 (0) | 2023.05.25 |
---|---|
수학과 동등합니다.Min & Math.최대 날짜 수? (0) | 2023.05.25 |
동일한 서버의 Apache 및 Node.js (0) | 2023.05.25 |
Xcode에서 iOS 시뮬레이터를 실행하고 검은색 화면을 받은 후 Xcode가 매달려 작업을 중지할 수 없습니다. (0) | 2023.05.25 |
배치 스크립트에서 랜덤을 사용하는 방법은 무엇입니까? (0) | 2023.05.25 |