我有一个200k文档的集合,每个文档包含一个" CustomerName"领域。大约有1k个独特的" customerName"值。 (该字段已编入索引)
我需要呈现这些客户名称的列表并为每个客户名称生成一个slug,以便我可以在我的路由URL中使用。
下一步是为每个customerName呈现一个页面,显示包含该customerName的所有文档。
这是我到目前为止所拥有的,
/// Customer.js
Model.findAll({
include: [{association: 'OtherModels', through: {attributes: []}}]
});
/// Customer.Controller.js
const rmaSchema = new Schema({
CustomerName: { type: String, index: true },
slug: String },
{ collection : 'mycompany' // collection name
});
rmaSchema.pre('save', function(next) {
this.slug = slugify(this.CustomerName) ;
next();
});
const rmaModel = mongoose.model('Rma', rmaSchema);
module.exports = rmaModel;
// function to slugify a name
function slugify(text) {
return text.toString().toLowerCase()
.replace(/\s+/g, '-') // Replace spaces with -
.replace(/[^\w\-]+/g, '') // Remove all non-word chars
.replace(/\-\-+/g, '-') // Replace multiple - with single -
.replace(/^-+/, '') // Trim - from start of text
.replace(/-+$/, ''); // Trim - from end of text
}
/// customer.ejs
function showCustomers(req, res){
Rma.distinct('CustomerName', function(err, customers) {
if (err){
res.status(404);
res.send('customers not found!');
}
res.render('pages/customers', {customers: customers});
});
};
module.exports = showCustomers;
答案 0 :(得分:0)
我不太了解你的控制器逻辑,但我们有一些具体的话题,这里是你如何引用路线中的slu ::
app.get('/rma/:slug', function(req, res, next) {
console.log(req.params.slug)
// mongo query to find slug
if (foundRecord) {
return res.render('pages/customer', {
customer: foundRecord
})
} else {
return res.render('404', { slug: req.params.slug })
}
})
你的slug功能看起来很不错。
我要提及的一件事是,在您当前的控制器中,您没有使用明确的return
,因此请务必注意,如果用户遇到404条件,您的API将会设置该标题可能会继续。我对res.send并不是100%肯定,但你绝对可以改为return res.send()
和return res.render()
来强化它。返回将确保它在此时退出该功能。
如果您遇到阻塞和去阻塞的问题,我建议您将slug与记录一起存储,如果用户更新了名称,也会更新它。
{
_id: 'g9sd76gft9s87dfgs8d7f'
CustomerName: 'Bob Alice',
CustomerNameSlug: 'Bob-Alice'
}
如上所述Mikey的评论,如果你没有独特的slu will,你会在你的路线中遇到命名冲突。
要解决这个问题,如果你将slug与Mongo DB中的每条记录一起存储,你可以找到使它独一无二的东西,但是如果你的客户只是通过点击你的UI来到达路线,我就会这样做。不要手动输入URL。您可以执行类似slugify(
$ {CustomerName} $ {timestamp} )
的操作,这将提供相当独特的保证。
嗯,我使用了一个模板字符串,StackOverflow语法高亮显示器似乎不喜欢由于双重重音使用。需要明确的是,这将与slugify(CustomerName + timestamp.toString())
的结果相同。这只是一个简单的连接。