如何在使用 mongoDB 对数据进行分页的 table 中实现后端搜索?

How to implement backend search within a table whose data is being paginated using mongoDB?

我想在分配给用户的系统 ID 列表中的相同 API(如果可能)内实施后端搜索。

系统 (ID) 分配给用户的集合:

{ 
    "_id" : ObjectId("62093266db5c0830fe3397ea"), 
    "email" : "naved@gmail.com",
    "role" : "owner", 
    "systemID" : [
        "12345678", 
        "20200302"
    ], 
    "mobile" : "9876543210"
}

系统 ID (bPID) 单独存储在另一个包含系统当前详细信息的集合中。

{ 
    "_id" : ObjectId("6212d42aab85a3b9f7559e02"), 
    "bPID" : "12345678", // primary key
    "bPVoltage" : 45.9,
    "capacity" : "5", 
    "alerts" : [ "201", "342" ],
    "state": 2,
    "stateOfCharge": 98
},
{ 
    "_id" : ObjectId("6212d42bab8ba3d9f7599ea2"), 
    "bPID" : "20200302", 
    "bPVoltage" : 45.9,
    "capacity" : "2", 
    "alerts" : [ "200" ],
    "state": 0,
    "stateOfCharge": 48
},
{ 
    "_id": ObjectId("6212d42aab85a3b9f7559e02"), 
    "bPID": "20200302", 
    "bPVoltage": 45.9,
    "capacity": "5", 
    "alerts": [ "315" ],
    "state": 1,
    "stateOfCharge": 78
}

现在我在前端有一个 table,其中分页数据填充在 table 中,上面有一个搜索框。

如果我输入一个 ID,如何实现搜索 returns 我只分配给该用户的匹配 ID 列表,例如,如果我输入 12,返回的 bPID 为 12348 或 12469,但仅如果它被分配给用户。我的 API 代码用于填充 table 中仅分配的 bPID 的结果,如下所示:

router.get('/getActiveSystems', async (req, res) => {
  const systemList = req.systemList;
  const { page, limit } = req.query;

  try {
    if (!page || !limit) {
      return res.status(400).json({
        message: 'Page and limit are required!',
        error: true
      });
    }

    const lastTenMinutes = moment().subtract(10, 'm').toDate();

    const options = {
      page: parseInt(page),
      limit: parseInt(limit),
      sort: {
        date: -1.0
      }
    };

    const query = [
      {
        $match: {
          bPID: {
            $in: systemList
          },
          date: {
            $gte: new Date(lastTenMinutes)
          }
        }
      },
      {
        $project: {
          bPID: 1.0,
          capacity: 1.0,
          alerts: 1.0,
          state: 1.0,
          stateOfCharge: 1.0
        }
      }
    ];

    const aggregate = BatteryPacks.aggregate(query);
    const systemDetails = await BatteryPacks.aggregatePaginate(aggregate, options);
    return res.status(200).json(systemDetails);
  } catch (error) {
    return res.status(500).json({
      message: 'Internal server error'
    });
  }
});

如果我没理解错的话,你可以这样做:

db.users.aggregate([
  {$match: {"_id": user_id}},
  {
    $project: {
      systemIDs: {
        $filter: {
          input: "$systemID",
          as: "item",
          cond: {$regexMatch: {input: "$$item",  regex: searchInput}}
        }
      }
    }
  },
  { $unwind: "$systemIDs"},
  {
    $lookup: {
      from: "systemIds",
      localField: "systemIDs",
      foreignField: "bPID",
      as: "systemIds"
    }
  },
  { $sort: { systemIDs: 1}},
  { $skip: 0},
  { $limit: 10}
])

$match 找到特定用户的地方,$project 仅过滤 systemID 与 searchInput 匹配的内容,而 $lookup 获取 systemID数据。其他步骤允许分页(本例中有 10 个结果)。

您可以看到它适用于 playground