programing

MongoDB에서 삭제 시 참조 개체 자동 제거

telecom 2023. 5. 25. 21:31
반응형

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

반응형