Mongoose - 多个数据库连接

Rao*_*old 3 mongoose mongodb node.js typescript

我想了解如何在 mongoose 全局承诺连接中的数据库之间切换。

我当前的连接是这样建立的 app.ts

import * as mongoose from 'mongoose';

...

try {
    await mongoose.createConnection(`mongodb://localhost:27017/db1`, {
        useNewUrlParser: true,
    })
    console.log("Connected")
} catch (error) {
    console.log(error)
}
Run Code Online (Sandbox Code Playgroud)

然后我在不同的文件中访问它 some.model.ts

import { Schema, Document, model } from 'mongoose';

const SomeSchema: Schema = new Schema({
  name: { type: String, required: true },
  owner: { type: string, required: true }
});
export default model('Some', SomeSchema);
Run Code Online (Sandbox Code Playgroud)

根据文档。

到目前为止,我们已经看到了如何使用 Mongoose 的默认连接连接到 MongoDB。有时我们可能需要向 Mongo 打开多个连接,每个连接都有不同的读/写设置,或者可能只是例如不同的数据库。在这些情况下,我们可以使用 mongoose.createConnection() 它接受已经讨论过的所有参数并为您返回一个新的连接。 const conn = mongoose.createConnection('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]', options);

我可以像这样创建多个数据库连接

try {
const db1 = await mongoose.createConnection(`mongodb://localhost:27017/db1`, {
    useNewUrlParser: true,
})
const db2 = await mongoose.createConnection(`mongodb://localhost:27017/db2`, {
    useNewUrlParser: true,
})
    console.log("Connected")
} catch (error) {
    console.log(error)
}
Run Code Online (Sandbox Code Playgroud)

我可以看到两者的联系 console.log(mongoose.connections)

但是我如何指定应该为模型使用哪个数据库some.model.ts

import { Schema, Document, model } from 'mongoose';

const SomeSchema: Schema = new Schema({
  name: { type: String, required: true },
  owner: { type: string, required: true }
});

export default SPECIFY_DATABASE.model('Some', SomeSchema);
Run Code Online (Sandbox Code Playgroud)

我发现像其他问题,但也有创造“localy”的连接,我需要使用许多不同的文件猫鼬的连接。

感谢您的回答,如果您需要更多解释,请现在告诉我。

Zla*_*tko 10

您需要实际返回连接,然后将给定模型注册到每个连接。为了澄清,您需要:

  • 创建(命名的,特定的)连接的东西
  • 模式
  • 您通过将模式注册到给定的连接来创建模型,
  • 你还需要一些东西来协调它。

例如,让我们有一个带有单个导出的“db.js”文件(我通常称之为“repo.js”),一个返回初始化数据库 Promise 的函数。您可以通过导入函数并等待数据库来使用它。

我有一个更长的例子,所以为简洁起见,省略了错误处理等。

import { createConnections } from './create-connections';
import { UsersSchema } from './users-schema';
import { PostsSchema } from './posts-schema';

let db: any;

export function getDatabase(): Promise<any> {
    if (this.db) return Promise.resolve(db);
    return createDatabases();
}

async function createDatabases() {
    const { db1, db2 } = await createConnections('mongodb://localhost/db1', 'mongodb://localhost/db2');
    const UserModel = db1.model('users', UserSchema);
    const PostModel = db2.model('posts', PostSchema);
    db = {
      UserModel,
      PostModel,
      // also if you need this
      connections: {
        db1,
        db2,
      }
    }
    return db;
}
Run Code Online (Sandbox Code Playgroud)

现在,我在'./create-connections'这里使用过,这几乎就是你所拥有的:

// create-connection.js
const { createConnection } = require('mongoose');

// You create connections by calling this function and giving it the URL to the server
export function createConnections(url1, url2) {
  const db1 = await createConnection(url1);
  const db2 = await createConnection(url2);
  return {
    db1,
    db2
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,假设您有两个模型:用户和帖子,让我们拥有它们的模式。

// users schema
import { Schema, Document } from 'mongoose';
export const UserSchema: Schema = new Schema({
  name: { type: String, required: true },
});

// posts schema
import { Schema, Document } from 'mongoose';
export const PostSchema: Schema = new Schema({
  text: { type: String, required: true },
  owner: { type: SchemaID, required: true }
});
Run Code Online (Sandbox Code Playgroud)

所以现在你需要把它全部绑定在那个 fdirst 文件中。

但是如何使用呢?正如我所说,因为它是异步的,所以你总是导入它并将它用作一个简单的异步 getDB:

// some controller, route handler, service etc.
import { getDatabase } from './get-database';

router.get('/users', async (req, res) => {
  const User = await getDatabase().UserModel;
  const users = await User.find();
  return res.json(users);
});

router.post('/posts', async (req, res) {
  const { text } = req.body;
  const owner = req.user.id;
  const Post = await getDatabase().PostModel;

  const post = await Post.create({ text, owner });
  return res.json(post);      
});
Run Code Online (Sandbox Code Playgroud)