活动数据正在存储,但MongoDB广告系列集合中的用户引用除外。如何仅呈现用户创建的广告系列,而不呈现每个用户的所有广告系列?用户登录网站后,需要此。
活动模式
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var campaignSchema = new Schema({
Title: {type: String},
Description: { type: String },
Rules: {} ,
Banner: { type: String },
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
});
module.exports = mongoose.model('Campaigns', campaignSchema);
用户架构
const bcrypt = require('bcryptjs');
const crypto = require('crypto');
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
username: String,
email: { type: String, unique: true },
password: String,
phonenumber: Number,
passwordResetToken: String,
passwordResetExpires: Date,
emailVerificationToken: String,
emailVerified: Boolean,
snapchat: String,
facebook: String,
twitter: String,
google: String,
github: String,
instagram: String,
linkedin: String,
steam: String,
quickbooks: String,
tokens: Array,
profile: {
name: String,
gender: String,
location: String,
website: String,
picture: String
}
}, { timestamps: true });
/**
* Password hash middleware.
*/
userSchema.pre('save', function save(next) {
const user = this;
if (!user.isModified('password')) { return next(); }
bcrypt.genSalt(10, (err, salt) => {
if (err) { return next(err); }
bcrypt.hash(user.password, salt, (err, hash) => {
if (err) { return next(err); }
user.password = hash;
next();
});
});
});
/**
* Helper method for validating user's password.
*/
userSchema.methods.comparePassword = function comparePassword(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, (err, isMatch) => {
cb(err, isMatch);
});
};
/**
* Helper method for getting user's gravatar.
*/
userSchema.methods.gravatar = function gravatar(size) {
if (!size) {
size = 100;
}
if (!this.email) {
return `https://gravatar.com/avatar/?s=${size}&d=blank`;
}
const md5 = crypto.createHash('md5').update(this.email).digest('hex');
return `https://gravatar.com/avatar/${md5}?s=${size}&d=blank`;
};
const User = mongoose.model('User', userSchema);
module.exports = User;
用于呈现用户创建的广告系列的路线。这是我要发送用户创建的广告系列详细信息的地方。
router.get('/camptab', function(req, res, next) {
User.findById({ userid:req.user.id })
.populate('campaign').exec((err, campaign) => {
res.render('camptab', { camplist : campaign });
})
});
活动数据正在存储,但MongoDB广告系列集合中的用户引用除外。如何仅呈现用户创建的广告系列,而不呈现每个用户的所有广告系列?用户登录网站后,需要此。
在您的用户架构中,您没有对广告系列的任何引用,因此您无法从用户中填充广告系列。
据我所知,您想通过用户ID获取用户信息和他/她的广告系列。
要填充广告系列,您需要使用virtual populate。
首先,将toJSON: { virtuals: true }
选项添加到您的用户架构,并按如下所示设置虚拟填充:(请注意,为了简化架构,我省略了大多数字段,您可以添加它们。)]
const userSchema = new mongoose.Schema( { username: String, email: { type: String, unique: true }, password: String }, { toJSON: { virtuals: true }, timestamps: true } ); userSchema.virtual("campaigns", { ref: "Campaigns", localField: "_id", foreignField: "user" });
假设我们有这个用户:
{ "_id": "5e2db40fd40cc1175cbfcd8a", "username": "Username1", "email": "[email protected]", "password": "123123", "createdAt": "2020-01-26T15:45:19.521Z", "updatedAt": "2020-01-26T15:45:19.521Z", "__v": 0 }
以及此用户的这2个广告系列:
{ "_id": "5e2db470d40cc1175cbfcd8b", "Title": "Campaign 1 title", "Description": "Campaign 1 description", "user": "5e2db40fd40cc1175cbfcd8a", "__v": 0 }, { "_id": "5e2db47ad40cc1175cbfcd8c", "Title": "Campaign 2 title", "Description": "Campaign 2 description", "user": "5e2db40fd40cc1175cbfcd8a", "__v": 0 }
现在您可以像回答中那样填充,但是猫鼬
findById
方法期望字符串值为_id。因此,您最好像这样替换您的获取路线:
router.get("/camptab", function(req, res, next) { User.findById(req.user.id) .populate("campaigns") .exec((err, campaign) => { if (err) { console.log(err); return res.status(500).send("Something went wrong"); } res.render("camptab", { camplist: campaign }); }); });
这将为您提供这样的结果,用户信息和他/她的广告系列:
{ "camplist": { "_id": "5e2db40fd40cc1175cbfcd8a", "username": "Username1", "email": "[email protected]", "password": "123123", "createdAt": "2020-01-26T15:45:19.521Z", "updatedAt": "2020-01-26T15:45:19.521Z", "__v": 0, "campaigns": [ { "_id": "5e2db470d40cc1175cbfcd8b", "Title": "Campaign 1 title", "Description": "Campaign 1 description", "user": "5e2db40fd40cc1175cbfcd8a", "__v": 0 }, { "_id": "5e2db47ad40cc1175cbfcd8c", "Title": "Campaign 2 title", "Description": "Campaign 2 description", "user": "5e2db40fd40cc1175cbfcd8a", "__v": 0 } ], "id": "5e2db40fd40cc1175cbfcd8a" } }
但是,如果您只想在没有用户信息的情况下使用给定用户ID的广告系列,而不对架构进行任何更改,则可以直接查询您的Campaigns集合,而无需进行任何填充。您唯一需要更改的就是使用
find
方法,并以user
作为查询。
router.get("/camptab", function(req, res, next) { let user = req.user.id; Campaign.find({ user }).exec((err, campaign) => { if (err) { console.log(err); return res.status(500).send("Something went wrong"); } res.render("camptab", { camplist: campaign }); }); });
这将给您这样的结果:
{
"camplist": [
{
"_id": "5e2db470d40cc1175cbfcd8b",
"Title": "Campaign 1 title",
"Description": "Campaign 1 description",
"user": "5e2db40fd40cc1175cbfcd8a",
"__v": 0
},
{
"_id": "5e2db47ad40cc1175cbfcd8c",
"Title": "Campaign 2 title",
"Description": "Campaign 2 description",
"user": "5e2db40fd40cc1175cbfcd8a",
"__v": 0
}
]
}
After implementing above my ejs template not showing campaign details.
**my ejs template like this below:**
<div class="container">
<table class="table table-bordered">
<thead class="bg-dark text-center">
<tr class="text-white">
<th>Title</th>
<th>Description</th>
<th>Pic</th>
</tr>
</thead>
<tbody class="text-center">
<%camplist.forEach(function(camp){%>
<tr>
<td><a href="campaign/<%=camp.Title%>"><%=camp.Title%> </a></td>
<td><%camp.Description%></td>
<td> <img src="campaign/<%=camp.Banner%>" style="width:100px; height:50px;" alt=""></td>
</tr>
<%})%>
My db looking like this