sql >> Database >  >> NoSQL >> MongoDB

Mongoose &Express:hoe u op de juiste manier gegevens verwijdert, maakt en opslaat die als referentie dienen

Ik denk dat je je schema's op een eenvoudigere manier moet herontwerpen, er zijn te veel verwijzingen tussen de modellen, en dit veroorzaakt problemen, je hebt bijvoorbeeld 5 db-toegang als je een opmerking wilt maken en 6 db-toegang als je dat wilt verwijder een opmerking.

Ik zou het gebruikersschema op deze manier maken en de berichten en commentaarreferenties verwijderen, maar later, wanneer we toegang willen krijgen tot de berichten van gebruikers, heb ik virtueel invullen.

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"
});

En in het berichtenschema heb ik de verwijzingen naar opmerkingen verwijderd. (Voor de eenvoud heb ik de velden voor leuk en niet leuk verwijderd.)

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"
});

Reactieschema kan blijven zoals het is.

Om nu een opmerking aan een bericht toe te voegen, hebben we slechts 2 db-toegang nodig, één om te controleren of een bericht bestaat en één om het bericht te maken.

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");
    }
  }
);

Laten we zeggen dat we deze 2 gebruikers hebben:

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

Gebruiker1 met _id:"5e216d74e7138b638cac040d" heeft dit bericht.

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

Laten we zeggen gebruiker2 met _id:"5e217192d204a26834d013e8" heeft twee keer gereageerd op dit bericht, zoals dit:

{
    "_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
}

Om een ​​opmerking te verwijderen, kunnen we de volgende route gebruiken, zoals je ziet hebben we de db-toegang verlaagd van 6 naar 3, en de code is korter en schoner.

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");
  }
});

Nu vraag je je misschien af, hoe krijg je toegang tot de berichten van een gebruiker? Aangezien we virtuele populatie hebben ingesteld in ons gebruikersschema, kunnen we de berichten als volgt vullen:

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

  res.send(result);
});


  1. MongoDB - Een verzameling maken

  2. LuaSocket, Lua 5.2 en Redis

  3. MongoDB verwerkt geen aggregatie met allowDiskUsage:True

  4. Kan een $text-zoekopdracht een gedeeltelijke overeenkomst opleveren?