如何使用MongoDB、Node.js及Handlebars模板在浏览器渲染聚合结果?
解决MongoDB聚合结果在Handlebars表格中渲染的问题
首先得指出你代码里的核心问题:MongoDB的aggregate方法是异步的,你现在直接把Revision.aggregate()的返回值赋给test,这个值并不是实际的聚合结果,而是一个查询对象,所以模板里根本拿不到有效数据。得把页面渲染逻辑放到聚合查询的回调函数里才行。
修正后端代码
把路由和聚合查询逻辑整合,确保拿到结果后再渲染页面:
// 定义聚合管道 var leastArticleRevision = [ {'$group': {'_id': "$title", 'numOfEdits': {$sum: 1}}}, {'$sort': {numOfEdits: 1}}, {'$limit': 5} ]; router.get('/', function(req, res){ // 执行聚合查询,在回调里处理结果 Revision.aggregate(leastArticleRevision, function(err, results){ if (err){ console.log("Aggregation Error:", err); // 返回错误提示页面 return res.render('index', { content: "聚合查询出错了", articles: [] }); } else { console.log("The least edited articles are: ", results); // 把聚合结果传给模板,用语义化的变量名更清晰 res.render('index', { content: "最少编辑的文章列表", articles: results }); } }); });
编写Handlebars模板(index.hbs)
接下来在你的Handlebars模板里,用{{#each}}循环遍历聚合结果,生成表格:
<h1>{{content}}</h1> <table border="1" cellpadding="8" cellspacing="0"> <thead> <tr> <th>文章标题</th> <th>编辑次数</th> </tr> </thead> <tbody> {{#each articles}} <tr> <!-- 聚合结果里的_id对应文章标题,numOfEdits是统计的编辑次数 --> <td>{{_id}}</td> <td>{{numOfEdits}}</td> </tr> {{else}} <tr> <td colspan="2" align="center">暂无数据</td> </tr> {{/each}} </tbody> </table>
关键说明
- 异步处理:必须在聚合查询的回调函数内部调用
res.render,确保拿到实际的查询结果后再传给模板,这是异步编程的核心要点。 - 模板循环:Handlebars的
{{#each}}可以直接遍历数组,{{else}}分支用来处理数组为空的情况,能提升页面的友好性。 - 变量命名:把传给模板的变量名改成
articles比test更语义化,不管是后端维护还是前端模板编写,都更容易理解。
这样修改后,当用户访问根路径时,后端会先执行聚合查询,拿到最少编辑的5篇文章数据,再把数据传给Handlebars模板,最终在浏览器里渲染出完整的表格。
内容的提问来源于stack exchange,提问作者PONCY
相关产品推荐
相关产品推荐

