如何在Node.js中查询MongoDB关联表数据并在EJS按匹配规则渲染
问题根因
你当前的实现是全量查询所有玩家数据后直接传到模板,遍历每场比赛时没有做场次匹配,所以所有玩家数据都会出现在每一场比赛的列表下。
解决方案
提供两种可选方案,更推荐使用方案一,数据库层面关联查询性能更高,避免全量数据传输到前端再过滤,适合数据量较大的场景。
方案一:后端用聚合关联查询(推荐)
直接通过MongoDB的$lookup算子关联两个集合,查询结果会直接把对应场次的玩家数据挂载到每场比赛的属性下,结构更清晰。
修改后端查询代码:
Games.aggregate([ { $lookup: { // 此处填MongoDB中Players集合的实际名称,默认是小写复数形式players from: "players", localField: "game", foreignField: "game", as: "players" } } ], (err, gamesWithPlayers) => { if (err) { // 可自行补充错误处理逻辑 return res.sendStatus(500) } res.render('score-board', { games: gamesWithPlayers }) })
修改EJS模板代码:
<% games.forEach(game => { %> <h3>Game <%= game.game %>:</h3> <table> <thead> <tr> <th>Player</th> <th>Points</th> </tr> </thead> <tbody> <% game.players.forEach(player => { %> <tr> <td class="player-name"><%- player.player %></td> <td><%- player.points %>pts</td> </tr> <% }) %> </tbody> </table> <% }) %>
方案二:仅修改EJS模板(适合小数据量场景)
如果不想改动后端查询逻辑,只需要在遍历玩家时增加场次过滤条件即可:
<% games.forEach(game => { %> <h3>Game <%= game.game %>:</h3> <table> <thead> <tr> <th>Player</th> <th>Points</th> </tr> </thead> <tbody> <% players.filter(p => p.game === game.game).forEach(player => { %> <tr> <td class="player-name"><%- player.player %></td> <td><%- player.points %>pts</td> </tr> <% }) %> </tbody> </table> <% }) %>
注意事项
你的Games Schema中game字段定义为String类型,需要保证Players集合中game字段的类型和其一致,如果存储为数字类型,可以把过滤条件改为p.game == game.game做隐式类型转换即可。
内容的提问来源于stack exchange,提问作者saintyusuf
相关产品推荐
相关产品推荐

