如何根据req.param更改MongoDB活动数据库?

时间:2019-05-10 20:13:35

标签: node.js express

我有一个本地化的维护数据库,该数据库将在没有Internet访问的局域网上运行。最近,我根据其他要求从SQL数据库迁移到了Mongo,我需要满足前进的需要,并且我正尝试通过新的express / mongo后端而不是我一直在运行的nginx / mariaDB来恢复现有功能。一旦我备份了该文件,就可以继续添加新要求...

我现在的问题是尝试基于req.param更改MongoDB中的活动数据库(使用猫鼬)。我可以在实际查询中使用这些参数,但希望为需要该应用程序的每个高级硬件集设置一个数据库。

示例:

http://1.2.3.4/api/HardwareA/tasks返回“硬件A”数据库的任务集合中的项目

http://1.2.3.4/api/HardwareB/tasks返回硬件B数据库的任务集合中的项目

我一直在尝试使用useDB()功能,但无法如上所述进行任何工作。我可以通过将数据库硬编码到mongoose.connection中来找到有效的路径,但这种方式并不是很动态。

在几个不同的文件中具有以下内容,这些文件可以与硬编码数据库一起工作,并且只需要尝试弄清楚如何尽早实现数据库更改即可。

我在其中具有合并参数,因为我尝试使用req.param.db进行以下操作以加载数据库,但是在初始构建时我总是得到未定义的req,这对我来说很有意义。只是不确定如何适当地执行此操作。所有这些特快的东西对我来说都是新的。我敢肯定这是我所没有看到的。

感谢您的协助。

来自package.json以获取版本参考。

"express": "^4.16.4",
"express-session": "^1.16.1",
"mongodb": "^3.2.3",
"mongoose": "^5.5.3",

api / index.js

const express = require('express')
const mongoose = require('mongoose')
const bodyParser = require('body-parser')
const cors = require('cors')
const app = express()

const mongoUser = 'User'
const mongoPass = 'superPass'
const mongoServer = '192.168.5.5'
const mongoPort = '27017'
/* const mongoDB = req.param.db || ''
const mongoURI = `mongodb://${mongoUser}:${mongoPass}@${mongoServer}:${mongoPort}/maintCenter${mongoDB}?authSource=admin` // fail A */

const mongoURI = `mongodb://${mongoUser}:${mongoPass}@${mongoServer}:${mongoPort}/maintCenter?authSource=admin`

mongoose.connect(mongoURI, {
  useNewUrlParser: true
})

// mount the router on the app
app.options('*', cors())
app.use(bodyParser.json())
app.use('/api', require('./routes'))

module.exports = app

api / routes / index.js *编辑-添加了此文件

const router = require('express').Router()
const mongoose = require('mongoose')

router.use('/:db/taskdata', require('./taskRoute'))

module.exports = router

api / routes / taskRoute.js

const express = require('express')
const mongoose = require('mongoose')

const taskRoute = express.Router({ mergeParams: true })

const Task = require('../models/taskModel')

// get all tasks
taskRoute.route('/').get(function(req, res) {
//gives mongoose.connection.useDB is not a function // Fail B
//mongoose.connection.useDB(`maintCenter${req.param.db}`)
  Task.find(function(err, tasks) {
    if (err) {
      res.json(err)
    } else {
      res.json(tasks)
    }
  })
})

module.exports = taskRoute

问题:

最终用户:我小组中3个或4个工作站点中大约有30个人。最根本不是技术性的。

平台:VueJS Web应用程序,axios用于提交。

单个数据库:考虑使用This Library作为多租户来进行操作,但是我对如何处理特定于硬件的备份/还原感到困惑。可能有一种简单的处理方法,但我找不到它,这使我像使用MariaDB一样回到了各个数据库。两者都不卖,只是恢复了我所拥有和知道的东西。

关于这个主题,我会为每个命令做两个发现吗?就像

Task.find(
  {
    hardware: 'A',
    somethingElse: '123'
  }
)

是否可以按照

的方式做更多的事情
tasks = Task.find(hardware: 'A')

taskRoute.route('/').get(function(req, res) {
  Task.find(function(err, tasks) {
    if (err) {
      res.json(err)
    } else {
      res.json(tasks)
    }
  })
})

我什至不知道那是否合理。只是想找出实现它的最佳整体方法。非常感谢您为我提供的有关检查的帮助。我已经阅读了2个星期,几天前得到了一些基本的代码,但这是迄今为止最长的。我希望以上内容能填充正确的数据。

2 个答案:

答案 0 :(得分:2)

执行此操作的好方法是将所有内容保留在同一数据库中,并在每个架构中定义一个hardware字段,该字段用于存储请求中的硬件名称。

然后,在端点上,您将发出Mongoose请求,仅影响将硬件字段设置为请求中的硬件的任务。

除非您有一个非常特定的要求,即强迫您使用多个数据库(肯定不是这种情况),否则即使您可能可行,也可能会误解您的数据库模式(但会导致imo不良代码) )。

Code for my previous answer

答案 1 :(得分:1)

之所以接受您的回答,是因为它为我提供了足够的详细信息,使我知道我正在失败,也许这不是错误的路径,但是对于我当前的技能水平而言,这并不容易。最终使用了mongo-tenant library,现在有了以下内容,我可以按照您在单个数据库中建议的那样进行过滤。以后我可以对用户进行只读和读写访问,这应该可以执行我需要执行的所有操作,因为我不需要按集合或类似的操作来分隔权限。

非常感谢您的帮助。 这是我结束的地方。

api / index.js(从上方不变)

api / routes / index.js(从上方不变)

api / routes / taskRoute.js

const express = require('express')

const taskRoute = express.Router({ mergeParams: true })

const Task = require('../models/taskModel')

// get all tasks
taskRoute.route('/').get(function(req, res) {
  const boundTask = Task.byTenant(req.params.db)
  console.log(req.param.db)
  boundTask.find(function(err, tasks) {
    if (err) {
      res.json(err)
    } else {
      res.json(tasks)
    }
  })
})

module.exports = taskRoute

api / models / taskModel.js

const mongoose = require('mongoose')
const mongoTenant = require('mongo-tenant')

const taskSchema = new mongoose.Schema(
  {
    taskID: {
      type: Number,
      unique: true,
      required: true,
      trim: true
    },
    taskName: String,
    category: String,
    lastCompletion: Date,
    detailDescription: Boolean,
    active: { type: Boolean, default: true }
  },
  { timestamps: true }
)

taskSchema.plugin(mongoTenant)

const Task = mongoose.model('Task', taskSchema)

module.exports = Task

然后在创建任务或保存任务时添加属性: tenantId: this.$route.param.db 按照我的Vue项目路线中的定义,它将拉动现有路线,因此将根据当前打开的页面创建任务。

通过这种方式,hardwareA / tasks只会挑选出正确的东西,一个模型集和一个数据库。

稍后可能会遇到无法预料的问题,但现在我想我可以继续进行现有内容的数据迁移。

非常感谢您协助获得有效的模型。我将无法允许他们以这种方式创建任意数据库,但无论如何这也许是最好的。我只是框架一些公认的通用术语,以便它们在需要时使用。