You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查询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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:05:26