【问题标题】:Update: Display First Occurance in ForEach loop in EJS and Node JS更新:在 EJS 和 Node JS 的 ForEach 循环中显示第一次出现
【发布时间】:2020-10-04 07:53:42
【问题描述】:

我想显示时间表集合中的所有数据,但我希望数据只显示教室名称一个。例如,我有 2 个 classroom_name 字段,即 6 Usaha。我只想要 EJS 表中的 6 Usaha 中的 1 个。

知道了,系统已经根据 Collections 中的记录数显示数据,在这种情况下是 2。

实际结果

6 Usaha
6 Usaha

预期结果

6 Usaha

这是我的实现代码。

EJS 文件

<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
                                        <thead>
                                            <tr>
                                                <th>Class</th>
                                                <th>Settings</th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            <% timetable.forEach(function (timetable) { %>
                                            <tr>
                                                <td><%= timetable.classroom.classroom_name %></td>
                                                <td><a class="button" href="/timetable_class/view/<%= timetable.classroom._id %>"</a>View&nbsp;</td>
                                            </tr>
                                            <% }) %>
                                        </tbody>

                                    </table>

服务器文件

router.get('/timetable_class',mid, function(req,res){
  Teacher.findById(req.session.userId).exec(function (error, user){
    if (error){
      return next(error);
    }else
    {
      Timetable.find({year:currentYear}).populate('classroom').exec(function(err, timetable) 
      {
        if (err) throw err;
        console.log(currentYear);
        console.log(timetable);
        res.render('admin_content/view_timetable_table',{timetable:timetable,  user:user});
      });
    }
  });
});

【问题讨论】:

  • 对于具有重复classroom.classroom_name 值的其他文档应该如何处理?您只想单独显示第一次出现吗?
  • 是的。我只想显示第一次出现。 @Tunmee

标签: node.js mongodb mongoose ejs


【解决方案1】:

您需要过滤掉具有重复 classroom.classroom_name 值的时间表文档,以便仅存在一个此类文档(第一个)用于呈现。这有点棘手,因为 classrrom_name 属性仅在查找另一个集合(教室)后才可用。

虽然对现有查询结果使用常规 javascript 过滤的明显解决方案会起作用,但更好、更有效的过滤方法是在数据库级别进行。这将有助于避免获取大量不需要的文档。

您可以使用 MongoDB 聚合根据其classroom.classroom_name 值查找、查找(类似于填充)和分组时间表文档,因此 db 查询的结果将是这样的 classroom.classroom_name 值对于每个时间表文件。代码如下:

router.get('/timetable_class',mid, function(req,res){
  Teacher.findById(req.session.userId).exec(function (error, user){
    if (error){
      return next(error);
    } else
    {
      // In place of .find() and .populate(), I'm using .aggregate()
      Timetable.aggregate([
        {
          // This is doing the same thing as the previous .find()
          $match: { year: currentYear }
        },
        // The stages($lookup and $set) below are doing what the previous
       // .populate() was doing
        {
          $lookup: {
            from: "Classroom",
            localField: "classroom",
            foreignField: "_id",
            as: "classroom"
          }
        },
        {
          $set: { classroom: { $arrayElemAt: [ "$classroom", 0] } }
        },
        // Group the documents with their classroom.classroom_name value
        {
          $group: {
            _id: "$classroom.classroom_name",
            doc: { $first: "$$ROOT" }
          }
        },
        // A bit of cleanup 
        { $replaceRoot: { newRoot: "$doc" } }
      ]).exec(function(err, timetable) 
      {
        // The query output is such that `classroom.classroom_name`
        // value is unique for each document
        if (err) throw err;
        console.log(currentYear);
        console.log(timetable);
        res.render('admin_content/view_timetable_table',{timetable:timetable,  user:user});
      });
    }
  });
});

有用的链接:

【讨论】:

  • 感谢您的解决方案!
猜你喜欢
  • 1970-01-01
  • 2019-10-30
  • 2020-07-13
  • 2016-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-05
相关资源
最近更新 更多