node.js - Mongoose - flere databaseforbindelser
Jeg vil forstå hvordan man bytter mellom databaser innenfor mongoose global promise-tilkobling.
Min nåværende tilkobling er etablert på denne måten 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)
}
Og så får jeg tilgang til det i forskjellige filer 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);
I følge dokumentasjonen.
Så langt har vi sett hvordan man kobler til MongoDB ved å bruke Mongoose sin standardtilkobling. Noen ganger kan vi trenge flere åpne tilkoblinger til Mongo, hver med forskjellige lese-/skriveinnstillinger, eller kanskje bare til forskjellige databaser for eksempel. I disse tilfellene kan vi bruke mongoose.createConnection(), som aksepterer alle argumentene som allerede er diskutert og returnerer en ny tilkobling for deg.
const conn=mongoose.createConnection('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]', options);
Jeg kan opprette flere databaseforbindelser på denne måten
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)
}
Jeg kan se begge tilkoblinger i console.log(mongoose.connections)
Men hvordan kan jeg spesifisere hvilken database som skal brukes for modellen i 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);
Jeg har funnet andre spørsmål som dette, men det blir opprettet forbindelser "lokalt". Jeg trenger å bruke Mongoose-forbindelse på tvers av mange forskjellige filer.
Takk for svarene, hvis du trenger mer forklaring, vennligst gi meg beskjed.
Svar #1
Du må faktisk returnere tilkoblingen, og deretter registrere en gitt modell til hver av tilkoblingene. For å klargjøre, du trenger:
- noe for å lage en (navngitt, spesifikk) forbindelse
- skjemaer
- du lager modeller ved å registrere skjemaer til de gitte forbindelsene,
- du trenger også noe for å orkestrere det.
Eksempel, la oss ha en "db.js"-fil (jeg kaller min vanligvis "repo.js") med en enkelt eksport, en funksjon som returnerer den initialiserte database-Promise. Du ville bruke den ved å importere funksjonen og vente på databasen.
Jeg har et litt lengre eksempel, så feilhåndtering osv. er utelatt for korthetens skyld.
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;
}
Nå har jeg brukt './create-connections' her, som nesten er det du har:
// 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
}
}
La oss nå si at du har to modeller: brukere og innlegg, la oss se på deres skjemaer.
// 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 }
});
Så nå må du binde alt i den første filen.
Men hvordan bruke det? Som jeg har sagt, siden det er asynkront, importerer du det alltid og bruker det som en enkel asynkron 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);
});
