如何获取Express / Mongo中特定用户的所有帖子列表?

时间:2020-02-05 06:44:44

标签: node.js mongodb mongoose

我有一个用户和帖子模型,并且有一个用户供稿,其中将显示该用户提交的所有帖子。

User.js

const mongoose = require("mongoose")
const bcrypt = require("bcrypt")
const Schema = mongoose.Schema

const userSchema = new Schema({
    username: { type: String, required: true },
    email: { type: String, required: true },
    password: { type: String, required: true },
}, { timestamps: true })


userSchema.pre("save", function (next) {
    if (this.password) {
        const salt = bcrypt.genSaltSync(10)
        this.password = bcrypt.hashSync(this.password, salt)
    }
    next()
})

userSchema.methods.confirmPassword = function (password) {
    return bcrypt.compareSync(password, this.password)
}


const User = mongoose.model("User", userSchema)

module.exports = User

Post.js

const mongoose = require("mongoose");
const Schema = mongoose.Schema;
var URLSlug = require("mongoose-slug-generator");

mongoose.plugin(URLSlug);

const postSchema = new Schema({
  postTitle: { type: String, required: true },
  postDescription: { type: String, required: true },
  userId: { type: Schema.Types.ObjectId, ref: "User" },
  slug: { type: String, slug: "title" }
}, { timestamps: true }
)

postSchema.pre("save", function (next) {
  this.slug = this.postTitle.split(" ").join("-");
  next();
});

const Post = mongoose.model("post", postSchema);

module.exports = post;

路线如下:

posts.js

router.post("/new", auth.verifyToken, postsController.newposts)
router.get("/list", postsController.listpostss)
router.get("/:id", postsController.findposts)
router.put("/:id/edit", postsController.updateposts)
router.delete("/:id/delete", postsController.deleteposts)

users.js

router.post("/register", usersController.registerUser)
router.post("/login", usersController.loginUser)
router.get("/me", auth.verifyToken, usersController.identifyUser)
router.get("/list", usersController.listUsers)
router.get("/:id", usersController.getUser)
router.put("/:id/edit", usersController.updateUser)
router.delete("/:id/delete", usersController.deleteUser)

因此,我只希望将用户提交的帖子显示在我的react应用程序的Feed组件上。

1 个答案:

答案 0 :(得分:1)

由于您没有用户发表的任何参考,因此可以使用virtual population

首先像这样更新用户架构:(请注意,我添加了toJSON: { virtuals: true }并定义了userSchema.virtual

const userSchema = new Schema(
  {
    username: { type: String, required: true },
    email: { type: String, required: true },
    password: { type: String, required: true }
  },
  { timestamps: true, toJSON: { virtuals: true } }
);

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

现在,您可以像正常人群一样填充用户的帖子:

router.get("/user-posts", async (req, res) => {
  try {
    const userId = req.user.id; //change this to logged -in user id
    const result = await User.findById(userId).populate("posts");
    res.send(result);
  } catch (err) {
    console.log(err);
    res.status(500).send("Something went wrong, check logs");
  }
});

假设我们有这个现有用户:

{
    "_id": "5e3a885ec511414a3c37a78c",
    "username": "metalHeadDev",
    "email": "metal@head.dev",
    "password": "123123",
    "createdAt": "2020-02-05T09:18:22.948Z",
    "updatedAt": "2020-02-05T09:18:22.948Z",
    "__v": 0,
    "id": "5e3a885ec511414a3c37a78c"
}

该用户的这2则帖子:

{
    "_id": "5e3a88e2c511414a3c37a78d",
    "postTitle": "title1",
    "postDescription": "description1",
    "userId": "5e3a885ec511414a3c37a78c",
    "slug": "title1",
    "createdAt": "2020-02-05T09:20:34.529Z",
    "updatedAt": "2020-02-05T09:20:34.529Z",
    "__v": 0
}

{
    "_id": "5e3a88f1c511414a3c37a78e",
    "postTitle": "title2",
    "postDescription": "description2",
    "userId": "5e3a885ec511414a3c37a78c",
    "slug": "title2",
    "createdAt": "2020-02-05T09:20:49.754Z",
    "updatedAt": "2020-02-05T09:20:49.754Z",
    "__v": 0
}

结果将是这样的:

{
    "_id": "5e3a885ec511414a3c37a78c",
    "username": "metalHeadDev",
    "email": "metal@head.dev",
    "password": "123123",
    "createdAt": "2020-02-05T09:18:22.948Z",
    "updatedAt": "2020-02-05T09:18:22.948Z",
    "__v": 0,
    "posts": [
        {
            "_id": "5e3a88e2c511414a3c37a78d",
            "postTitle": "title1",
            "postDescription": "description1",
            "userId": "5e3a885ec511414a3c37a78c",
            "slug": "title1",
            "createdAt": "2020-02-05T09:20:34.529Z",
            "updatedAt": "2020-02-05T09:20:34.529Z",
            "__v": 0
        },
        {
            "_id": "5e3a88f1c511414a3c37a78e",
            "postTitle": "title2",
            "postDescription": "description2",
            "userId": "5e3a885ec511414a3c37a78c",
            "slug": "title2",
            "createdAt": "2020-02-05T09:20:49.754Z",
            "updatedAt": "2020-02-05T09:20:49.754Z",
            "__v": 0
        }
    ],
    "id": "5e3a885ec511414a3c37a78c"
}

作为替代方法,我们可以使用mongodb聚合框架。 此解决方案不需要更改架构,因此是首选。

const ObjectId = require("mongoose").Types.ObjectId;

router.get("/user-posts", async (req, res) => {
  try {
    const userId = req.user.id; //change this to logged -in user id
    const result = await User.aggregate([
      {
        $match: {
          _id: ObjectId(userId)
        }
      },
      {
        $lookup: {
          from: "posts",        //must be collection name for posts
          localField: "_id",
          foreignField: "userId",
          as: "posts"
        }
      }
    ]);

    if (result.length > 0) {
      res.send(result[0]);
    } else {
      res.status(404).send("User not found");
    }
  } catch (err) {
    console.log(err);
    res.status(500).send("Something went wrong, check logs");
  }
});

这将产生相同的结果。

相关问题