node.js - Mongoose - conexiuni multiple la baze de date
Vreau să înțeleg cum să comut între baze de date în cadrul conexiunii globale de promisiune Mongoose.
Conexiunea mea actuală este stabilită în acest mod 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)
}
Și apoi accesez acest lucru în fișiere diferite 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);
Conform documentației.
Până acum am văzut cum să ne conectăm la MongoDB folosind conexiunea implicită a Mongoose. Uneori, poate fi necesar să avem mai multe conexiuni deschise către Mongo, fiecare cu setări diferite de citire/scriere, sau poate doar către baze de date diferite, de exemplu. În aceste cazuri putem folosi mongoose.createConnection(), care acceptă toți parametrii deja discutați și returnează o conexiune nouă pentru tine.
const conn=mongoose.createConnection('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]', options);
Pot crea mai multe conexiuni la baza de date în felul acesta
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)
}
Pot vedea ambele conexiuni în console.log(mongoose.connections)
Dar cum pot specifica ce bază de date ar trebui folosită pentru Model în 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);
Am găsit alte întrebări asemănătoare, dar acolo conexiunile sunt create „local”, eu am nevoie să folosesc conexiunea mongoose în mai multe fișiere diferite.
Mulțumesc pentru răspunsuri, dacă aveți nevoie de mai multe explicații vă rog să mă anunțați.
Răspuns #1
Trebuie să returnați efectiv conexiunea și apoi să înregistrați un model dat la fiecare dintre conexiuni. Pentru a clarifica, aveți nevoie de:
- ceva pentru a crea o conexiune (denumită, specifică)
- scheme
- creezi modele prin înregistrarea schemelor la conexiunile date,
- de asemenea, ai nevoie de ceva care să o orchestreze.
De exemplu, să avem un fișier „db.js” (eu de obicei îl numesc „repo.js”) cu un singur export, o funcție care returnează Promise-ul bazei de date inițializate. L-ai folosi importând funcția și așteptând db-ul.
Am un exemplu puțin mai lung, așa că gestionarea erorilor etc. este omisă pentru concizie.
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;
}
Acum, am folosit './create-connections' aici, care este aproape ceea ce aveți:
// 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
}
}
Acum, să zicem că aveți două modele: utilizatori și postări, să avem schemele lor.
// 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 }
});
Deci acum trebuie să le legi pe toate în acel prim fișier.
Dar cum să-l folosești? Așa cum am spus, deoarece este asincron, îl imporți întotdeauna și îl folosești ca un simplu getDB asincron:
// 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);
});
