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

Node.js MongoDB中如何通过Mongoose Schema实现单问题多答案存储?

Hey Deepak,很高兴能帮你解决这个问题!你已经搭好了基础的问答Schema,接下来咱们一步步实现多答案存储和独立问题/回答页面的需求:

1. 先优化你的MongoDB Schema(可选但强推)

你当前的answer: [{String}]只能存纯文本答案,但实际场景里,咱们通常需要记录更多信息(比如回答者、发布时间这些)。我建议把它扩展成对象数组,这样灵活性更高:

var questionSchema = mongoose.Schema({
  questions: { type: String, required: true }, // 加个required确保问题不能为空
  details: { type: String },
  tags: [{ type: String }], // 改成数组支持多个标签,比单个字符串实用多了
  answers: [{ // 字段名改成answers更语义化
    content: { type: String, required: true }, // 答案内容必填
    author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, // 如果有用户模型,关联回答者ID
    createdAt: { type: Date, default: Date.now } // 自动记录发布时间
  }]
});
const Question = mongoose.model('Question', questionSchema);

如果暂时不需要额外信息,原来的[{String}]也能用,但扩展后能支持更多后续功能,比如显示回答者、按时间排序答案等。

2. 实现独立问题页面

问题页面的核心是展示单个问题详情+所有关联的答案,后端需要写一个接口根据问题ID查询完整数据,再传给前端渲染:

后端接口(Express示例)

app.get('/questions/:id', async (req, res) => {
  try {
    // 查询问题,同时把答案按最新时间排序
    const question = await Question.findById(req.params.id).sort({'answers.createdAt': -1});
    if (!question) {
      return res.status(404).send('Question not found');
    }
    // 渲染问题页面模板,把question数据传过去
    res.render('question-page', { question });
  } catch (err) {
    res.status(500).send('Something went wrong: ' + err.message);
  }
});

前端模板(EJS示例)

在模板里遍历答案列表,展示每个答案的内容和附加信息:

<!-- 问题详情区域 -->
<div class="question-container">
  <h1><%= question.questions %></h1>
  <p class="question-details"><%= question.details %></p>
  <div class="tags">
    <% question.tags.forEach(tag => { %>
      <span class="tag"><%= tag %></span>
    <% }) %>
  </div>
</div>

<!-- 答案列表区域 -->
<div class="answers-container">
  <h3>Answers (<%= question.answers.length %>)</h3>
  <% question.answers.forEach(answer => { %>
    <div class="answer-card">
      <p class="answer-content"><%= answer.content %></p>
      <small class="answer-meta">
        Posted on <%= answer.createdAt.toLocaleString() %>
        <% if (answer.author) { %>by User <%= answer.author %> <% } %>
      </small>
    </div>
  <% }) %>
  <!-- 加个按钮跳转到回答页面 -->
  <a href="/answers/new/<%= question._id %>" class="btn">Write an Answer</a>
</div>

3. 实现独立回答页面

回答页面需要先展示问题的简要信息,再提供表单让用户提交新答案:

后端渲染回答页面的接口

app.get('/answers/new/:questionId', async (req, res) => {
  try {
    const question = await Question.findById(req.params.questionId);
    if (!question) {
      return res.status(404).send('Question not found');
    }
    res.render('answer-page', { question });
  } catch (err) {
    res.status(500).send('Something went wrong: ' + err.message);
  }
});

提交答案的后端接口

app.post('/answers/:questionId', async (req, res) => {
  try {
    const { content } = req.body;
    const question = await Question.findById(req.params.questionId);
    
    if (!question) {
      return res.status(404).send('Question not found');
    }
    // 把新答案添加到answers数组里
    question.answers.push({ 
      content,
      // 如果有登录用户,这里可以加author: req.user._id(需要用passport之类的中间件)
    });
    await question.save();
    // 提交成功后跳回问题页面,让用户看到自己的答案
    res.redirect(`/questions/${req.params.questionId}`);
  } catch (err) {
    res.status(500).send('Failed to submit answer: ' + err.message);
  }
});

回答页面模板(EJS示例)

<div class="answer-form-container">
  <h2>Answer to: <%= question.questions %></h2>
  <p class="question-preview"><%= question.details %></p>
  
  <form action="/answers/<%= question._id %>" method="POST">
    <textarea name="content" rows="8" placeholder="Type your detailed answer here..." required></textarea>
    <button type="submit" class="submit-btn">Submit Your Answer</button>
  </form>
</div>

4. 一些额外的小优化

  • 数据验证:除了Schema里的required,还可以用express-validator做前端和后端的双重验证,避免非法数据。
  • 答案排序:前面的查询已经加了sort({'answers.createdAt': -1}),让最新的答案排在最前面,符合用户习惯。
  • 分页(可选):如果以后答案很多,可以给答案列表加分页功能,避免页面加载过慢。

内容的提问来源于stack exchange,提问作者DD93

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:37:17