Поскольку у вас нет ссылок от пользователя к записи, вы можете использовать виртуальное население для этого:
Сначала обновите схему пользователя следующим образом: (обратите внимание, что я добавил 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");
}
});
Это даст тот же результат.