NodeJS MongoDB Mongoose – получение _.id вновь созданной схемы

У меня есть приложение, которое позволяет пользователям оценивать книги. Книги вызываются из API Google Книг. Я сохраняю копию книги в своей БД только тогда, когда пользователь отправляет свою оценку.

reviews.put("/:id/new", async (req, res) => {
  let url = await `https://www.googleapis.com/books/v1/volumes/${req.params.id}`;
  console.log(url);
  await request(url, { json: true }, async (error, response, data) => {
    let newRating;
    Book.findOne({ id: req.params.id }, (err, result) => {
      if (err) console.log(err.message);
      if (result) {
        if (req.body.stars !== undefined) {
          newRating = /* some math formula */
        } else {
          newRating = /* some math formula */
        }
      } else {
        newRating = req.body.stars;
      }
    });
    Book.findOneAndUpdate(
      {
        id: req.params.id
      },
      {
        id: data.id,
        id: data.id,
        title: data.volumeInfo.title,
        description: data.volumeInfo.description,
        img: data.volumeInfo.imageLinks.thumbnail,
        author: data.volumeInfo.authors,
        rating: newRating,
        $inc: {
          ratingCount: 1
        }
      },
      {
        upsert: true,
        returnNewDocument: true
      },
      (err, book) => {
        console.log(book) // If its creating a new document, book returns null. If the book is already in the DB, book returns the document. 
        Review.create({
          rating: req.body.stars,
          review: req.body.review,
          reviewer: req.session.currentUser._id,
          book: book._id // <-- ERROR, cannot read property "_.id" of null
        });
      }
    );
  });

  res.redirect("/");
});

Проблема в том, что book возвращает null при новом создании. Но это прекрасно работает, если кто-то уже оценил его. Я пытался использовать .save(), но это не сработало. Как еще я могу получить _.id только что созданной книги?

Любая помощь приветствуется. Спасибо!


person Community    schedule 20.11.2019    source источник


Ответы (2)


Вы передаете неверные параметры запроса. Вы должны использовать:

new: bool — если true, вернуть измененный документ, а не оригинал.

upsert: bool — создает объект, если он не существует. по умолчанию ложно.

Обновите метод следующим образом:

Book.findOneAndUpdate(
      {
        id: req.params.id
      },
      {
        id: data.id,
        id: data.id,
        title: data.volumeInfo.title,
        description: data.volumeInfo.description,
        img: data.volumeInfo.imageLinks.thumbnail,
        author: data.volumeInfo.authors,
        rating: newRating,
        $inc: {
          ratingCount: 1
        }
      },
      {
        upsert: true,
        new: true
      },
      (err, book) => {
        console.log(book) // If its creating a new document, book returns null. If the book is already in the DB, book returns the document. 
        Review.create({
          rating: req.body.stars,
          review: req.body.review,
          reviewer: req.session.currentUser._id,
          book: book.id // <-- ERROR, cannot read property "_.id" of null
        });
      }

См. документы.

person Samuel Goldenbaum    schedule 20.11.2019

Используйте 'new': true следующим образом: { upsert: true, 'new': true }.

Это должно вернуть обновленный документ.

person Shihab    schedule 20.11.2019