sql >> Database teknologi >  >> NoSQL >> MongoDB

Mongoose &Express:Hvordan man korrekt fjerner, opretter og gemmer data, der er reference

Jeg synes du skal redesigne dine skemaer på en enklere måde, der er for mange referencer mellem modellerne, og det giver problemer, f.eks har du 5 db adgang når du vil lave en kommentar, og 6 db adgang når du vil slet en kommentar.

Jeg ville oprette brugerskemaet som dette ved at fjerne indlæg og kommentarreferencer, men senere, når vi vil have adgang til indlæg fra brugere, konfigurerede jeg virtuelt udfylde.

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

Og i indlægsskemaet fjernede jeg kommentarreferencerne.(For nemheds skyld fjernede jeg likes og dislikes-felter.)

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

Kommentarskema kan forblive, som det er.

For nu at tilføje en kommentar til et opslag, har vi kun brug for 2 db adgang, en til at kontrollere, om et indlæg findes, og en til at oprette indlægget.

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

Lad os sige, at vi har disse 2 brugere:

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

Bruger1 med _id:"5e216d74e7138b638cac040d" har dette indlæg.

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

Lad os sige bruger2 med _id:"5e217192d204a26834d013e8" kommenterede dette indlæg to gange sådan her:

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

For at fjerne en kommentar kan vi bruge følgende rute, som du ser, har vi reduceret db-adgangen fra 6 til 3, og koden er kortere og renere.

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 kan du spørge, hvordan får du adgang til indlæg fra en bruger? Da vi opsætter virtuel udfyldning i vores brugerskema, kan vi udfylde indlæggene sådan her:

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

  res.send(result);
});


  1. Hvordan sammenligner man to strenge i mongoDB fjederdata?

  2. Mongodb concat int og streng

  3. Læsning af DBname.system.indexes mislykkedes på Atlas-klyngen af ​​mongobee efter oprettelse af forbindelse

  4. MongoDB feltrækkefølge og dokumentpositionsændring efter opdatering