MongoDB,正确设置OneToMany,ManyToOne关系方法

时间:2019-01-26 18:53:41

标签: mongodb typescript mongoose

我正在尝试正确设置oneToMany,ManyToOne关系方法,到目前为止,我的结果(下面的伪代码)。我正在使用Typegoose(基本上是带类型的Mongoose),如果您以前从未使用过,那就不用担心了,无论如何这都与架构有关。我想讨论“ createBook”方法,如您所见,我依次使用“ await,await”,这使其效率非常低,我可以使用promise,并在该方法的末尾写Promise.all(bookQuery, authorQuery),但是我仍然存在错误处理问题,如果其中一个失败,那么其他仍然可以成功,那是不好的(正确的:如果其中一个失败,其他应该检索所做的任何更改)。我应该如何正确,有效地编写“ createBook”方法?

class Author extends Typegoose {
  @prop()
  fullName: string;

  @prop({ ref: Book, default: [] })
  books: Ref<Book>[];
}

class Book extends Typegoose {
  @prop()
  title: string;

  @prop({ ref: Author })
  author: Ref<Author>;
}

async createBook(title, authorId): Promise<Book> {
    const book = await new this.bookRepository({
      title,
      author: ObjectId(authorId)
    }).save();

    await this.authorRepository.updateOne(
      { _id: authorId },
      { $push: { books: Types.ObjectId(book.id) } }
    );

    return book;
  }

1 个答案:

答案 0 :(得分:1)

第一种方法是

async createBook(title, authorId): Promise<Book> {
  const book = new this.bookRepository({
    title,
    author: ObjectId(authorId)
  }).save();

  const author = this.authorRepository.updateOne(
    { _id: authorId },
    { $push: { books: Types.ObjectId(book.id) } }
  );
  try {
    await Promise.all([book, author])
    return book;
  } catch (e) {
    console.log(e)
    await Promise.all([
      this.bookRepository.deleteOne({_id: book._id}),
      this.authorRepository.updateOne(
        { _id: authorId },
        { $pull: { books: Types.ObjectId(book.id) } 
      }
    )]
  }
}

第二种方法是使用MongoDB Transactions。但是,它来自Mongo 4.0版本,仅在副本集上使用。此外,从4.2版本开始,交易也将在分片集合中提供