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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 10:15:01