MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Mongoose &Express:Cara Menghapus, Membuat &Menyimpan data yang menjadi referensi dengan benar

Saya pikir Anda perlu mendesain ulang skema Anda dengan cara yang lebih sederhana, ada terlalu banyak referensi di antara model, dan ini menyebabkan masalah, misalnya Anda memiliki akses 5 db ketika Anda ingin membuat komentar, dan akses 6 db ketika Anda ingin hapus komentar.

Saya akan membuat skema pengguna seperti ini menghapus posting dan referensi komentar, tetapi nanti ketika kami ingin mengakses posting dari pengguna, saya mengatur pengisian virtual.

const UserSchema = new Schema(
  {
    name: {
      type: String,
      required: true
    },
    email: {
      type: String,
      required: true,
      unique: true
    },
    password: {
      type: String,
      required: true
    },
    avatar: {
      type: String
    },
    date: {
      type: Date,
      default: Date.now
    }
  },
  {
    toJSON: { virtuals: true }
  }
);

UserSchema.virtual("posts", {
  ref: "Post",
  localField: "_id",
  foreignField: "user"
});

Dan dalam skema posting, saya menghapus referensi komentar. (Untuk mempermudah saya menghapus bidang suka dan tidak suka.)

const PostSchema = new Schema(
  {
    user: {
      type: Schema.Types.ObjectId,
      ref: "User"
    },
    text: {
      type: String,
      required: true
    },
    date: {
      type: Date,
      default: Date.now
    }
  },
  {
    toJSON: { virtuals: true }
  }
);

PostSchema.virtual("comments", {
  ref: "Comment",
  localField: "_id",
  foreignField: "post"
});

Skema komentar dapat tetap apa adanya.

Sekarang untuk menambahkan komentar ke postingan, kita hanya membutuhkan akses 2 db, satu untuk memeriksa apakah postingan ada, dan satu lagi untuk membuat postingan.

router.post(
  "/comment/:id",
  [
    auth,
    [
      check("text", "Text is required")
        .not()
        .isEmpty()
    ]
  ],
  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    try {
      const post = await Post.findById(req.params.id);
      if (!post) {
        return res.status(404).json({ msg: "Post not found" });
      }

      let comment = new Comment({
        text: req.body.text,
        post: req.params.id,
        user: req.user.id
      });

      comment = await comment.save();

      res.json(comment);
    } catch (err) {
      console.error(err.message);
      res.status(500).send("Server Error");
    }
  }
);

Katakanlah kita memiliki 2 pengguna ini:

{
    "_id" : ObjectId("5e216d74e7138b638cac040d"),
    "name" : "user1"
}
{
    "_id" : ObjectId("5e217192d204a26834d013e8"),
    "name" : "user2"
}

Pengguna1 dengan _id:"5e216d74e7138b638cac040d" memiliki pos ini.

{
    "_id": "5e2170e7d204a26834d013e6",
    "user": "5e216d74e7138b638cac040d",
    "text": "Post 1",
    "date": "2020-01-17T08:31:35.699Z",
    "__v": 0,
    "id": "5e2170e7d204a26834d013e6"
}

Katakanlah user2 dengan _id:"5e217192d204a26834d013e8" mengomentari posting ini dua kali seperti ini:

{
    "_id" : ObjectId("5e2172a4957c02689c9840d6"),
    "text" : "User2 commented on user1 post1",
    "post" : ObjectId("5e2170e7d204a26834d013e6"),
    "user" : ObjectId("5e217192d204a26834d013e8"),
    "date" : ISODate("2020-01-17T11:39:00.396+03:00"),
    "__v" : 0
},
{
    "_id": "5e21730d468bbb7ce8060ace",
    "text": "User2 commented again on user1 post1",
    "post": "5e2170e7d204a26834d013e6",
    "user": "5e217192d204a26834d013e8",
    "date": "2020-01-17T08:40:45.997Z",
    "__v": 0
}

Untuk menghapus komentar, kami dapat menggunakan rute berikut, seperti yang Anda lihat, kami menurunkan akses db dari 6 menjadi 3, dan kode lebih pendek dan lebih bersih.

router.delete("/comment/:id/:comment_id", auth, async (req, res) => {
  try {
    const comment = await Comment.findById(req.params.comment_id);

    if (!comment) {
      return res.status(404).json({ msg: "Post do not have this comment" });
    }

    if (comment.user.toString() !== req.user.id) {
      return res.status(401).json({ msg: "User not authorized" });
    }

    await comment.remove();

    // resend the comments that belongs to that post
    const postComments = await Comment.find({ post: req.params.id });
    res.json(postComments);
  } catch (err) {
    console.error(err.message);
    res.status(500).send("Server Error");
  }
});

Sekarang Anda mungkin bertanya, bagaimana cara mengakses posting dari pengguna? Karena kami menyiapkan populasi virtual dalam skema pengguna kami, kami dapat mengisi posting seperti ini:

router.get("/users/:id/posts", async (req, res) => {
  const result = await User.findById(req.params.id).populate("posts");

  res.send(result);
});


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Bagaimana cara memutuskan teknologi NoSQL mana yang akan digunakan?

  2. Adakah yang pernah menggunakan database objek dengan data dalam jumlah besar?

  3. Apakah ada cara untuk memulihkan dokumen yang baru dihapus di MongoDB?

  4. Bagaimana cara menginstal mongodb di Elastic Beanstalk?

  5. MongoDB:mencoba membaca Long dari JSON menyebabkan java.lang.Integer tidak dapat dilemparkan ke java.lang.Long