#mongodb #mongoose
#mongodb #мангуст
Вопрос:
У меня есть 3 коллекции, пользователи, сообщения и комментарии.
Схема пользователя
{
posts: [{ type: Schema.Types.ObjectId, ref: 'Post' }],
likes: {
comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }],
posts: [{ type: Schema.Types.ObjectId, ref: 'Post' }],
}
}
Схема публикации
{
author: { type: Schema.Types.ObjectId, ref: 'User' },
likes: [{ type: Schema.Types.ObjectId, ref: 'User' }],
comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }],
}
Схема комментариев
{
author: { type: Schema.Types.ObjectId, ref: 'User' },
post: { type: Schema.Types.ObjectId, ref: 'Post', },
}
Прямо сейчас это шаги, которые я делаю, чтобы удалить сообщение и все, что с ним связано, например, удаление идентификатора сообщения из поля сообщений автора документа, лайков пользователей в сообщении, комментариев, лайков пользователей в комментариях.
Это функция, которую я использую, и она работает, и все отлично, но мне интересно, есть ли лучший способ решения этой проблемы?
PostSchema.statics.deletePost = async function (postId) {
const post = await this.findById(postId);
const commentIds = post.comments;
await Promise.all([
User.findByIdAndUpdate(
post.author,
{ $pull: { posts: postId } },
),
User.updateMany(
{ _id: { $in: post.likes } },
{ $pull: { 'likes.posts': postId } },
),
commentIds.map(async (commentId) => {
const comment = await Comment.findById(commentId);
User.findByIdAndUpdate(
comment.author._id,
{ $pull: { comments: commentId } },
);
User.updateMany(
{ _id: { $in: comment.likes } },
{ $pull: { 'likes.comments': commentId } },
);
}),
this.findByIdAndDelete(postId),
]);
return post._id;
};
Комментарии:
1. Для чистого кода вы должны использовать
await
каждое отдельное обещание. И с массивом обещаний, которые вы должны использоватьPromise.all
. В противном случае ваш код в порядке.
Ответ №1:
Ваш код может создать несоответствие в базе данных.
при работе с несколькими документами используйте новую функцию ТРАНЗАКЦИЙ С НЕСКОЛЬКИМИ ДОКУМЕНТАМИ в MongoDB 4. Это означает, что либо все документы / коллекция будут обновлены, либо нет, если что-то пошло не так. Транзакция в целом будет атомарной.
или
Эффективно разрабатывайте схему, которая включает в себя все ваши 3 разные схемы. Потому что операция над одним документом является атомарной. читайте здесь https://docs.mongodb.com/manual/core/transactions /