如何查询Mongoose数据库获取单条数据?多分类单篇博客EJS展示实现
1. 如何查询Mongoose数据库以获取单条数据?
嘿,查询Mongoose单条数据其实很简单,常用的有这几个实用方法:
- 使用
findById():如果你知道文档的_id,这是最直接的方式,比如:
Blog.findById("60d21b4667d0d8992e610c85") .then(blog => { if (blog) { console.log("找到的博客:", blog); } else { console.log("没有找到对应的文档"); } }) .catch(err => console.error("查询出错:", err));
- 使用
findOne():可以根据任意查询条件匹配第一条符合的文档,比如按分类找第一篇:
Blog.findOne({ categ: "sports" }) .then(blog => { // 处理查询到的单篇博客数据 }) .catch(err => console.error(err));
- 用async/await简化异步写法:现在Node.js对这个语法支持很友好,代码更直观:
async function getSingleBlog() { try { const blog = await Blog.findOne({ categ: "fashion" }); if (blog) { console.log(blog); } } catch (err) { console.error(err); } } getSingleBlog();
2. 首页每个分类仅展示一篇博客的实现方案
看你已经在用async.parallel并行处理多分类查询了,刚好可以在每个任务里用findOne()或者find().limit(1)来获取每个分类的单篇博客,我帮你把代码补全并优化:
完善后的路由代码
const async = require('async'); // 确保已安装async包:npm install async app.get("/index", function(req, res, next){ const output = { sports: null, fashion: null, food: null, headlines: null }; async.parallel([ // 查询sports分类的最新一篇博客 function(cb){ Blog.findOne({ categ: "sports" }) .sort({ createdAt: -1 }) // 按创建时间倒序,取最新的一篇 .exec((err, blog) => { if (err) return cb(err); output.sports = blog; cb(null); }); }, // 查询fashion分类的最新一篇博客 function(cb){ Blog.findOne({ categ: "fashion" }) .sort({ createdAt: -1 }) .exec((err, blog) => { if (err) return cb(err); output.fashion = blog; cb(null); }); }, // 查询food分类的最新一篇博客 function(cb){ Blog.findOne({ categ: "food" }) .sort({ createdAt: -1 }) .exec((err, blog) => { if (err) return cb(err); output.food = blog; cb(null); }); }, // 查询headlines分类的最新一篇博客 function(cb){ Blog.findOne({ categ: "headlines" }) .sort({ createdAt: -1 }) .exec((err, blog) => { if (err) return cb(err); output.headlines = blog; cb(null); }); } ], function(err){ if (err) return next(err); // 把错误传给错误处理中间件 // 渲染EJS视图并传递数据 res.render("index", { blogData: output }); }); });
EJS视图渲染代码(index.ejs)
在首页视图里,你可以这样渲染每个分类的单篇博客:
<div class="category-section"> <h2>体育</h2> <% if (blogData.sports) { %> <div class="blog-card"> <h3><%= blogData.sports.title %></h3> <p><%= blogData.sports.content.substring(0, 100) %>...</p> <!-- 截取部分内容展示 --> <a href="/blog/<%= blogData.sports._id %>">阅读全文</a> </div> <% } else { %> <p>暂无体育类博客</p> <% } %> </div> <div class="category-section"> <h2>时尚</h2> <% if (blogData.fashion) { %> <div class="blog-card"> <h3><%= blogData.fashion.title %></h3> <p><%= blogData.fashion.content.substring(0, 100) %>...</p> <a href="/blog/<%= blogData.fashion._id %>">阅读全文</a> </div> <% } else { %> <p>暂无时尚类博客</p> <% } %> </div> <!-- 重复上述结构渲染food和headlines分类 -->
额外小建议
如果你觉得重复代码太多,可以把查询单个分类的逻辑封装成函数:
function getSingleBlogByCategory(categ, cb) { Blog.findOne({ categ }) .sort({ createdAt: -1 }) .exec(cb); }
这样在async.parallel里直接调用这个函数,代码会更简洁。另外,也可以用async/await替代async.parallel,不需要额外安装依赖,写法更清爽:
app.get("/index", async function(req, res, next){ try { const [sportsBlog, fashionBlog, foodBlog, headlinesBlog] = await Promise.all([ Blog.findOne({ categ: "sports" }).sort({ createdAt: -1 }), Blog.findOne({ categ: "fashion" }).sort({ createdAt: -1 }), Blog.findOne({ categ: "food" }).sort({ createdAt: -1 }), Blog.findOne({ categ: "headlines" }).sort({ createdAt: -1 }) ]); const blogData = { sports: sportsBlog, fashion: fashionBlog, food: foodBlog, headlines: headlinesBlog }; res.render("index", { blogData }); } catch (err) { next(err); } });
内容的提问来源于stack exchange,提问作者AustinTNM
相关产品推荐
相关产品推荐

