노드js MongodB-다대여 응용 예시

지난 글에서 나는 단세입자와 다세입자 소프트웨어 체계 구조를 비교했다.오늘 우리는 여러 명의 세입자를 처리할 수 있도록 간단한 응용 프로그램을 구축하는 방법을 볼 것이다.우리는 깨끗한 nodejs,mongodb,mongoose를 사용하여 대상 모델링을 진행할 것입니다.
고객이 회사 데이터베이스에 로그인하여 CRUD 작업을 수행할 수 있도록 API를 구축해야 한다고 생각해 봅시다.우리의 자원은 한계가 있기 때문에 고객의 데이터를 격리하고 신속하게 확장할 수 있는 능력이 필요하다.모든 고객을 위해 새로운 응용 프로그램의 실례를 개발하는 데 너무 많은 시간과 정력을 들일 것이다.우리는 새로운 고객을 쉽게 추가할 수 있기를 바란다.
우리는 고객 데이터를 격리하고 새로운 고객을 쉽게 추가할 수 있도록 어떻게 이런 응용 프로그램을 설계하는지 연구할 것이다.우리는 단지 간단한 예를 하나 말할 뿐, 응용 프로그램에서 어떻게 이런 방법을 사용하는지 이해할 수 있기를 바랍니다.

npm i dontenv mongodb mongoose
touch app.js app.js에서 자동 실행 함수를 만듭니다. 이것은 우리의 시작입니다.
;(async function main() {
  console.log(employees)
})()
mkdir services서비스 카탈로그를 사용하여 생성mongo.connect.js합니다.
이제 족제비랑 Dotenv를 수입할 거예요.
그리고 데이터베이스의 초기 연결로 돌아가는 함수를 만들 것입니다.
import mongoose from 'mongoose'
import dotenv from 'dotenv'
dotenv.config()
const mongoOptions = {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  autoIndex: true,
  connectTimeoutMS: 10000,
  socketTimeoutMS: 30000,
}

function connectDB() {
  return new Promise((resolve, reject) => {
    const mongoURL = `mongodb://${process.env.MONGO_USER}:${process.env.MONGO_PASSWORD}@${process.env.MONGO_IP}:${process.env.MONGO_PORT}/?authSource=admin`
    mongoose
      .connect(mongoURL, mongoOptions)
      .then((conn) => {
        console.log('connected')
        resolve(conn)
      })
      .catch((error) => reject(error))
  })
}

export default connectDB 
좋아, 지금 우리는 이미 몬godb와 연락을 맺었어.좋습니다. 데이터베이스와의 연결을 어떻게 처리합니까?데이터베이스를 닫고 여는 작업은 매우 비싸기 때문에 우리는 다른 방법을 사용할 것이다.우리는 몬고 클라이언트 중 연결 탱크라는 것이 있다.
연결 탱크는 드라이버가 관리하는 개방적이고 언제든지 사용할 수 있는 데이터베이스 연결 캐시입니다.응용 프로그램은 틈새 없이 연못에서 연결을 가져오고, 동작을 실행하며, 연결을 연못으로 되돌려줍니다.연결 탱크는 라인이 안전하다.
MongoDB 클라이언트는 기본적으로 5개의 풀 크기입니다. 이것은 우리가 한 번에 5개의 병렬 작업을 수행할 수 있다는 것을 의미합니다.다른 작업은 연결이 풀로 돌아올 때까지 기다려야 합니다.다행히도, 우리는 앞에서 정의한 몬고 옵션 설정에서 전달을 통해 연못의 크기를 쉽게 늘릴 수 있다.
풀 연결의 이점
연결 탱크는 응용 프로그램의 지연과 새로운 연결을 만드는 횟수를 줄이는 데 도움이 된다.
연결 풀은 시작할 때 연결을 생성합니다.응용 프로그램은 수동으로 연결을 풀로 되돌릴 필요가 없습니다.반대로 연결은 자동으로 풀로 돌아간다.
일부 접속은 활성 상태이고 일부 접속은 비활성 상태이지만 사용할 수 있습니다.응용 프로그램이 연결을 요청하고 풀에 사용 가능한 연결이 있으면 새 연결을 만들 필요가 없습니다.
정의된 탱크가 클수록 우리의 데이터베이스 서비스는 자원을 필요로 한다.
알겠습니다. 폴더 모델을 만들고 employeeSchama.js, tenantSchema.js 세입자가 이 프로그램을 사용할 고객을 대표할 것입니다.세입자마다 데이터베이스가 하나씩 있는데,employeeSchema는 직원 데이터의 청사진으로 사용될 것이다.
import mongoose from 'mongoose'

const employeeSchema = mongoose.Schema({
  employeeId: {
    type: String,
    unique: true,
  },
  name: {
    type: String,
  },
  companyName: {
    type: String,
  },
})
export default employeeSchema
import mongoose from 'mongoose'

const tenantSchema = mongoose.Schema({
  name: {
    type: String,
  },
  email: {
    type: String,
  },
  password: {
    type: String,
  },
  companyName: {
    type: String,
    unique: true,
  },
})

export default tenantSchema
이제 프로그램의 모든 내용을 가져올 수 있습니다.js 파일
import connectDB from './services/mongo.connect.js'
import TenantSchema from './models/tenantSchema.js'
import EmployeeSchema from './models/employeeSchema.js'

// Indicates which Schemas are used by whom
const CompanySchemas = new Map([['employee', EmployeeSchema]])
const TenantSchemas = new Map([['tenant', TenantSchema]])


/** Switch db on same connection pool
 * @return new connection
 */
const switchDB = async (dbName, dbSchema) => {
  const mongoose = await connectDB()
  if (mongoose.connection.readyState === 1) {
    const db = mongoose.connection.useDb(dbName, { useCache:true })
    // Prevent from schema re-registration
    if (!Object.keys(db.models).length) {
      dbSchema.forEach((schema, modelName) => {
        db.model(modelName, schema)
      })
    }
    return db
  }
  throw new Error('error')
}

/**
 * @return model from mongoose
 */
const getDBModel = async (db, modelName) => {
  return db.model(modelName)
}

다음 예는 데이터베이스에 존재하는 검사가 포함되지 않기 때문에 존재하지 않는db 이름을 전달하면 새로운 데이터베이스를 만들 것입니다
getDBModel은 데이터베이스의 등록 모델을 얻을 수 있도록 합니다.
가짜 고객을 만들기 위해 함수를 작성합시다

const initTennants = async () => {
  const tenantDB = await switchDB('AppTenants', TenantSchemas)
  const tenant = await getDBModel(tenantDB, 'tenant')
  await tenant.deleteMany({})
  const tenantA = await tenant.create({
    name: 'Steve',
    email: '[email protected]',
    password: 'secret',
    companyName: 'Apple',
  })
  const tenantB = await tenant.create({
    name: 'Bill',
    email: '[email protected]',
    password: 'secret',
    companyName: 'Microsoft',
  })
  const tenantC = await tenant.create({
    name: 'Jeff',
    email: '[email protected]',
    password: 'secret',
    companyName: 'Amazon',
  })
}

우리의 주 방법에서 함수를 호출하다await initTennants()현재 우리는 데이터베이스가 하나 있는데, 그 안에는 세 명의 고객이 있다.
다음은 또 다른 함수입니다. 검사할 수 있습니다.
const getAllTenants = async () => {
  const tenantDB = await switchDB('AppTenants', TenantSchemas)
  const tenantModel = await getDBModel(tenantDB, 'tenant')
  const tenants = await tenantModel.find({})
  return tenants
}
현재 우리는 모든 고객을 위해 회사 이름을 가진 독립된 데이터베이스를 만들고 모든 데이터베이스에 직원을 만들 것이다.
const initEmployees = async () => {
  const customers = await getAllTenants()
  const createEmployees = customers.map(async (tenant) => {
    const companyDB = await switchDB(tenant.companyName, CompanySchemas)
    const employeeModel = await getDBModel(companyDB, 'employee')
    await employeeModel.deleteMany({})
    return employeeModel.create({
      employeeId: Math.floor(Math.random() * 10000).toString(),
      name: 'John',
      companyName: tenant.companyName,
    })
  })
  const results = await Promise.all(createEmployees)
}
회사 데이터베이스당 직원 명단
const listAllEmployees = async () => {
  const customers = await getAllTenants()
  const mapCustomers = customers.map(async (tenant) => {
    const companyDB = await switchDB(tenant.companyName, CompanySchemas)
    const employeeModel = await getDBModel(companyDB, 'employee')
    return employeeModel.find({})
  })
  const results = await Promise.all(mapCustomers)
  return results
}
이것이 최후의 결말이다.

저희의 주요 기능은 이렇습니다.
;(async function main() {
  await initTennants()
  await initEmployees()
  const tenants = await getAllTenants()
  const employees = await listAllEmployees()
  console.log(tenants)
  console.log(employees)
})()
좋습니다. 이 예시를 바탕으로 고객을 인증하고 데이터베이스에서 데이터를 추출할 수 있는 기능이 완비된 API를 개발할 수 있습니다.
읽어주셔서 감사합니다.
만약 당신이 그 중에서 어떤 것을 배웠다면 like를 누르면 비슷한 내용을 더 많이 만들 것입니다:)
Github repo

좋은 웹페이지 즐겨찾기