首页 > 解决方案 > 需要在嵌套对象 mongoose 中查找未使用的数字

问题描述

我正在尝试创建一个 Express 网络服务器,它执行以下操作 - 注册并登录 用户登录后,用户将被重定向到“控制面板”,他们在其中选择 docker 容器的规范。

猫鼬模式

  email: String,
  password: String,
  docker: {
    site: String,
    adminpwd: String,
    hostPort: Number,
    cpus: Number,
    memory: Number,
    storage: Number
  }
})

docker 对象在控制面板页面中的帖子之后附加到电子邮件和密码字段。

app.post('/control-setup/:userid',
//validation
[
  body('site').isURL({allow_underscores: true}),
  body('admin').isLength({ min: 6 })
], (req,res) => {
   const errors = validationResult(req);
     if (!errors.isEmpty()) {
       return res.status(400).json({ errors: errors.array() });
}
const userid = req.params.userid
//Setup or Edit
var site = req.body.site
var adminpwd = req.body.admin
var cpus = req.body.cpus
var memory = req.body.memory
var storage = req.body.storage
//Needs a function to get the next available port
var hostPort = findhostPort()
//Cutting https:// from input
var site_name = site.slice(8)
//Save or Edit in DB
Users.updateOne({_id: userid}, {docker: {site: site, adminpwd: adminpwd, hostPort: hostPort, cpus: cpus, memory: memory, storage: storage}}, {upsert: true, new: true},
  function (err, result) {
  if (err) throw err
  console.log('Docker Parameters Setup in User' + result)
  res.redirect(userid)
})
})

问题出在hostPort变量中,我正在尝试创建一个将通过 mongoDb 并找到可用端口的函数。

我尝试使用 for 循环,但它不起作用。我显然在这里错过了正确的逻辑。

非常感谢一些帮助,因为我是 NodeJs 和整个开发的新手

标签: node.jsmongoose

解决方案


您可以使用distinct查找所有已使用的端口,然后生成一个空闲端口号。

const ALL_POSSIBLE_PORT_NUMBERS = [...]

function async findhostPort () {
  const usedPorts = await User.distinct('docker.hostPort')
  for (let port of ALL_POSSIBLE_PORT_NUMBERS) {
    if (userPorts.indexOf(port) == -1) {
      return port
    }
  }
}

一些警告:

  • 您将需要创建docker.hostPort一个唯一字段,以便数据库在尝试保存重复的 hostPort 时会引发错误,因为对此方法的同时请求将获得相同的端口号。
  • 我假设您有一个包含所有可能端口号的数组,因为某些端口范围受到限制,您可能希望保留一些供内部使用
  • 随着您获得更多模型,使用distinct会变得更慢。如果出现问题,您可以考虑在内存中缓存未使用端口的列表,并在每次创建新端口时从中删除。

推荐阅读