Mongoose에서 캐스케이드 스타일 삭제
MySQLs 외부 키를 사용하는 것과 유사하게 Mongoose에서 부모의 자식을 모두 삭제하는 방법이 있습니까?
예를 들어 MySQL에서는 외부 키를 할당하고 삭제 시 캐스케이드로 설정합니다.따라서 클라이언트를 삭제하면 모든 응용프로그램 및 관련 사용자도 제거됩니다.
최상위 수준에서:
- 클라이언트 삭제
- 스위프 스테이크 삭제
- 제출 삭제
스위프 티켓과 제출에는 모두 client_id 필드가 있습니다.제출에는 sweepstakes_id 및 client_id 필드가 모두 있습니다.
지금 저는 다음 코드를 사용하고 있으며 더 나은 방법이 있어야 한다고 생각합니다.
Client.findById(req.params.client_id, function(err, client) {
if (err)
return next(new restify.InternalError(err));
else if (!client)
return next(new restify.ResourceNotFoundError('The resource you requested could not be found.'));
// find and remove all associated sweepstakes
Sweepstakes.find({client_id: client._id}).remove();
// find and remove all submissions
Submission.find({client_id: client._id}).remove();
client.remove();
res.send({id: req.params.client_id});
});
이것은 Mongoose의 주요 사용 사례 중 하나입니다.'remove' 미들웨어
clientSchema.pre('remove', function(next) {
// 'this' is the client being removed. Provide callbacks here if you want
// to be notified of the calls' result.
Sweepstakes.remove({client_id: this._id}).exec();
Submission.remove({client_id: this._id}).exec();
next();
});
이쪽으로 전화를 걸 때client.remove()이 미들웨어는 종속성을 정리하기 위해 자동으로 호출됩니다.
만약 당신의 추천서가 다른 방법으로 저장된다면,client의 배열을 가지고 있습니다.submission_ids그런 다음 승인된 답변과 유사한 방법으로 다음을 정의할 수 있습니다.submissionSchema:
submissionSchema.pre('remove', function(next) {
Client.update(
{ submission_ids : this._id},
{ $pull: { submission_ids: this._id } },
{ multi: true }) //if reference exists in multiple documents
.exec();
next();
});
그러면 클라이언트의 참조 배열에서 제출 ID가 제거됩니다.submission.remove().
여기 제가 찾은 또 다른 방법이 있습니다.
submissionSchema.pre('remove', function(next) {
this.model('Client').remove({ submission_ids: this._id }, next);
next();
});
여기 있는 모든 답변에는 다음이 있습니다.pre스키마에 할당되어 있지 않습니다.post.
제 해결책은 다음과 같습니다. (몽구스 6+ 사용)
ClientSchema.post("remove", async function(res, next) {
await Sweepstakes.deleteMany({ client_id: this._id });
await Submission.deleteMany({ client_id: this._id });
next();
});
정의에 따라 게시물은 프로세스가 종료된 후 실행됩니다.pre => process => post.
여기서 제공되는 다른 솔루션과 어떻게 다른지 궁금하실 것입니다.서버 오류 또는 해당 클라이언트의 ID를 찾을 수 없으면 어떻게 합니까?사전에, 그것은 모든 것을 삭제할 것입니다.sweeptakes그리고.submissions삭제 프로세스가 시작되기 전에client따라서 오류가 발생할 경우 다른 문서를 한 번 캐스케이드로 삭제하는 것이 좋습니다.client기본 문서가 삭제됩니다.
비동기 및 대기는 여기서 선택할 수 있습니다.그러나 삭제 진행 중인 경우 사용자가 "삭제될" 계단식 문서 데이터를 얻지 못하도록 대용량 데이터에 대해 중요합니다.
결국, 제가 틀릴 수도 있습니다. 이것이 코드에 있는 누군가에게 도움이 되기를 바랍니다.
모델
const orderSchema = new mongoose.Schema({
// Множество экземпляров --> []
orderItems: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'OrderItem',
required: true
}],
...
...
});
asyncHandler(옵션)
const asyncHandler = fn => (req, res, next) =>
Promise
.resolve(fn(req, res, next))
.catch(next)
module.exports = asyncHandler;
콘트롤러
const asyncHandler = require("../middleware/asyncErrHandler.middleware");
// **Models**
const Order = require('../models/order.mongo');
const OrderItem = require('../models/order-item.mongo');
// @desc Delete order
// @route DELETE /api/v1/orders/:id
// @access Private
exports.deleteOrder = asyncHandler(async (req, res, next) => {
let order = await Order.findById(req.params.id)
if (!order) return next(
res.status(404).json({ success: false, data: null })
)
await order.remove().then( items => {
// Cascade delete -OrderItem-
items.orderItems.forEach( el => OrderItem.findById(el).remove().exec())
}).catch(e => { res.status(400).json({ success: false, data: e }) });
res.status(201).json({ success: true, data: null });
});
https://mongoosejs.com/docs/api/model.html#model_Model-remove
언급URL : https://stackoverflow.com/questions/14348516/cascade-style-delete-in-mongoose
'codememo' 카테고리의 다른 글
| 다른 데이터 구조 대신 어레이를 사용하는 이유는 무엇입니까? (0) | 2023.05.23 |
|---|---|
| 파일 트리 다이어그램을 그리는 데 사용할 도구 (0) | 2023.05.23 |
| [] 및 {} vs list()와 dict() 중 어떤 것이 더 낫습니까? (0) | 2023.05.18 |
| 옵션 매개 변수를 오버로드로 대체하는 것이 획기적인 변화입니까? (0) | 2023.05.18 |
| Mongoose 스키마에서 다른 스키마를 참조하는 방법은 무엇입니까? (0) | 2023.05.18 |