我有一个用户和帖子模型,并且有一个用户供稿,其中将显示该用户提交的所有帖子。
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组件上。
答案 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");
}
});
这将产生相同的结果。