I'm following Mongoose Connection Docs to create multiple Databases Connections on express app. When i import my schema scoped to a connection i can't use models functions such like .find || .findOne etc.. and i get the next error
UserSchema.find is not a function
Is there something that i miss to add or is something i'm making wrong ??
Here is Schema code:
models/user.js
const { Schema } = require('mongoose');
const UserSchema = new Schema({
name: { type: String},
lastname: { type: String}
});
module.exports = UserSchema;
And then i create the connection with the model scooped to it.
databases/connection_1.js
const mongoose = require('mongoose');
const { Keys } = require('../keys');
const conn = mongoose.createConnection(
`mongodb://${Keys.DatabaseUser}:${Keys.DatabasePassword}#${Keys.DatabaseHost}/${Keys.DatabaseShema}`
, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: true
});
conn.model('User', require('../models/user'), 'Users')
module.exports = conn;
But when i try to use my Schema to fetch the data of the Database i get next error:
UserSchema.find is not a function
routes/index.js
const app = require('express').Router();
const UserSchema = require('../models/user');
app.get('/index', async (req,res) => {
console.log(await UserSchema.find({name: 'Jhon Doe'}))
})
module.exports = app;
Related
data is not saving in mongodb compass . i have used node js to connect to mongodb . a router is also there . model schema is also present .inside thunder client body i have passed a json according to model schema . app listen is working fine and connection to mongodb is also successful . but i could not see those passed data in my mongodb.literally i have tried everything but could not get any solution how to save my data ?
db.js (mongo server)
const mongoose = require('mongoose');
const mongoURI = "mongodb://localhost:27017/"
const connectToMongo = ()=>{
mongoose.connect(mongoURI, { useNewUrlParser: true,useUnifiedTopology:true },()=>{
console.log("Connected to Mongo Successfully");
})
}
module.exports = connectToMongo;
index.js (express and mongo server)
const connectToMongo = require('./db'); //here we import db.js from the above
const express = require('express');
connectToMongo();
const app = express();
const port = 3000;
app.use(express.json());
// Available Routes
app.use('/api/auth', require('./routes/auth')) //one route ./api/auth is the route
app.listen(port, () => {
console.log(`iNotebook backend listening at http://localhost:${port}`)
})
auth router
const express = require("express")
const User = require("../models/User") //User schema described below.
const router = express.Router()
router.get("/",(req,res)=>{
console.log(req.body)
const user=User(req.body)
user.save()
res.send(req.body)
})
module.exports = router
User schema inside model folder
const mongoose = require('mongoose');
const { Schema } = mongoose;
const UserSchema = new Schema({
name:{
type: String,
required: true
},
email:{
type: String,
required: true,
unique: true
},
password:{
type: String,
required: true
}
});
const User = mongoose.model('user', UserSchema);
module.exports = User;
picture of thunder client
here you can see https://localhost:300/api/auth is the router . in body i have given name ,email,password and response i am getting right . and also it is showing connected to mongo successfully.
picture of mongodb compass.
where my passed body data that is name,email,password is saving in mongodb compass
You should instantiate the new instance of User with new and await the Promise after save:
router.post("/", async (req,res)=>{
try {
const user= new User(req.body);
await user.save();
res.send(req.body);
} catch (e) {
res.send('error');
}
})
module.exports = router
Program description: I have a program that accepts a post request (request) of a "hometask" with its name, description, importance and group parameters provided. I need the provided group parameter to be identified as a collection name in the database (each collection is going to correspond to specific group and so each group will have a collection of hometasks-documents). Each new document should be created with Mongoose schema object.
Problem: I know that in Python's pymongo when addressing an unexisting collection it's being created automatically, however, in mongoose this turns out not to be the case. I have trouble providing the collection name to the new document-object. When providing {collection: request.group} in a new object in api/hometask.js, the error message started appearing when new requests were made: MongooseError: document must have an _id before saving. I still cannot understand what can be the cause of this problem. I will appreciate any help!
Main folder architecture:
server.js
const express = require('express')
require('dotenv').config()
const mongoose = require('mongoose')
const morgan = require('morgan')
const path = require('path')
let app = express();
const port = process.env.PORT || 3000;
mongoose.connect(process.env.uri, { useNewUrlParser: true })
.then(db => console.log('[ok] connected to db))
.catch(err => console.error(err))
app.use(express.json())
app.use(express.urlencoded({extended: false}))
app.use(morgan('dev'))
app.use('/api/hometasks', require('./api/hometask'))
app.use('/', express.static(path.join(__dirname, '../dist')))
app.listen(port)
api/hometask.js
const express = require('express');
const router = express.Router();
const Record = require('../models/hometask')
router.post('/', async (req, res) => {
let request = req.body
const record = new Record(request, {collection:request.group});
try {
await record.save();
res.json({
status: 'success'
});
} catch (err) {
console.log(err)
}
})
module.exports = router
models/hometask.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
let Record = new Schema({
name: {
type: String,
required: true
},
description: {
type: String,
required: true
},
importance: {
type: Boolean,
required: true
},
group: {
type: String,
required: true
}
});
module.exports = mongoose.model('hometask', Record);
In mongoose the collection name is set per model, not per document.
Note that the Model constructor does not take an options object.
You should be setting the collection name in the call to mongoose.model when you create the model, not when you create a document from that model.
i am trying to retrieve my data from mongoose schema to my route ( say using an app named insomnia just like postman) so evertime i run the route i am getting and empty array, what is wrong with it ?
app.js
const express=require('express');
const bodyparser=require('body-parser');
const app=express();
app.use(bodyparser.urlencoded({extended:false}));
const User=require('./db/models/user').User;
require('./db/mongo');
app.get("/api/user",function(req,res){
User.find().then(function(x){
res.send(x)
console.log(req.body)
})
})
app.listen(3000);
mongo.js
const mongoose = require('mongoose');
db=mongoose.connect('mongodb://localhost/chatter_dev',
{useNewUrlParser:true});
var db = mongoose.connection;
db.once('open', function callback () {
console.log("h");
});
module.exports =mongoose;
user.js
const mongoose=require('mongoose');
const userschema=new mongoose.Schema({
username:{
type:String,
unique:true,
required:true
},
email:{
type:String
},
firstname:String,
lastname:String},{
timestamps:true}
)
exports.User=mongoose.model("User",userschema)
Before doing any work trying to get data OUT, ya gotta get a little data IN. Get into mongo and insert a few records manually. Baby steps can help you diagnose the issue.
can you try this
User.find((err, users) => {
if (err) res.status(500).send(err);
else res.json(users);
});
**App.js**
const express = require('express');
const app = express();
const mongoose = require('mongoose');
const User = require('./models/users');
const options = {
useNewUrlParser: true,
useCreateIndex: true
};
mongoose.connect('mongodb://localhost/chatter_dev', options)
.then(connected => console.log(`Database connection establised`))
.catch(err => console.error(err));
app.get('/api/users', (req, res, next) => {
User.find().then(user => res.send(user)).catch(err => console.error(err));
})
app.listen(3000);
**Users.js (model)**
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
username:{
type:String,
unique:true,
required:true
},
email:{
type:String
},
firstname:String,
lastname:String
}, {timestamps: true});
module.exports = mongoose.model('User', userSchema);
Currently I have this code for my connection mongoose.js:
var mongoose = require('mongoose');
var uriUtil = require('mongodb-uri');
var mongodbUri = 'mongodb://localhost/db_name';
var mongooseUri = uriUtil.formatMongoose(mongodbUri);
mongoose.connect(mongooseUri);
module.exports = mongoose;
File that requires the connection is test.js:
var mongoose = require('../model/mongoose');
var schema = mongoose.Schema({...});
How can I update mongoose.js to use multiple connections with mongoose.createConnection(...) function?
I start with changes only for one connection when I do changes like that:
var mongoose = require('mongoose');
mongoose.createConnection('mongodb://localhost/db_name');
mongoose.open('localhost');
module.exports = mongoose;
I get "undefined is not a function".
If I use this code:
var mongoose = require('mongoose');
db = mongoose.createConnection('mongodb://localhost/db_name');
db.open('localhost');
module.exports = mongoose;
I get "Error: Trying to open unclosed connection"
Any advice?
Mongoose handling connections via connections pool
http://mongoosejs.com/docs/connections.html
You can use server: {poolSize: 5} option for increase/decrease pool (number of parallel connections)
If you need connections to different databases look here
Mongoose and multiple database in single node.js project
Example of multiple connections:
var mongoose = require('mongoose')
var conn = mongoose.createConnection('mongodb://localhost/db1');
var conn2 = mongoose.createConnection('mongodb://localhost/db2');
var Schema = new mongoose.Schema({})
var model1 = conn.model('User', Schema);
var model2 = conn2.model('Item', Schema);
model1.find({}, function() {
console.log("this will print out last");
});
model2.find({}, function() {
console.log("this will print out first");
});
OK. With your example I found a solution that fit my needs.
mongoose.js
var mongoose = require('mongoose');
mongoose.main_conn = mongoose.createConnection('mongodb://localhost/main');
mongoose.admin_conn = mongoose.createConnection('mongodb://localhost/admin');
module.exports = mongoose;
content.js
var mongoose = require('../model/mongoose');
var schema = mongoose.Schema({...});
/// functions here
schema.statics.func_a(){...};
schema.statics.func_b(){...};
// And finaly updated only one line
//exports.Content = mongoose.model('Content', schema);
exports.Content = mongoose.main_conn.model('Content', schema);
The only thing, is it OK to add connection objects to mongoose object or may be there is more elegant solution.
config.js
module.exports = {
default: 'main',
main: 'mongodb://localhost/main',
admin: 'mongodb://localhost/admin',
};
connection.js
const mongoose = require('mongoose');
const config = require('./config');
mongoose.Promise = global.Promise;
function createConnection(name) {
return mongoose.createConnection(config[name]);
}
module.exports = createConnection(config[config.default]);
module.exports.on = createConnection;
model.js (custom class)
const connection = require('./connection');
class Model {
constructor(name, data) {
this.data = data;
return this.connection().model(name, data.schema);
}
connection() {
if (this.data.connection) {
return connection.on(this.data.connection);
}
return connection;
}
}
module.exports = Model;
user.js
const Schema = require('mongoose').Schema;
const conn = require('./connection');
const Model = require('./model');
const userSchema = new Schema({
name: String,
email: String,
password: String
});
// USING MONGOOSE MODEL
// default connection
const UserM1 = conn.model('User', userSchema);
// admin connection
const UserM2 = conn.on('admin').model('User', userSchema);
// USING CUSTOM MODEL
// default connection
const UserC1 = new Model('User', {
schema: userSchema
});
// admin connection
const UserC2 = new Model('User', {
schema: userSchema,
connection: 'admin'
});
I am able to save request the data if I explicitly define in my express model the structure, but I am not able to save record if I do not explicitly define the data structure.
For example I am able to save if I have this in my model
....
module.exports = mongoose.model('Form', new Schema({
name: String,
password: String,
admin: Boolean
}));
...
...
but I am not able to save it if I have it like this
module.exports = mongoose.model('Form', new Schema());
Here is my model
// get an instance of mongoose and mongoose.Schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// set up a mongoose model and pass it using module.exports
module.exports = mongoose.model('Form', new Schema());
And here is my Router
apiRouter.post('/forms/createForm', function(req, res) {
var form = new Form(req.body);
form.save(function(err) {
if (err) throw err;
console.log('Form saved successfully');
res.json({ success: true });
});
});
Thanks
Ok I got that working.
There is a strict false option that I can use to define the schemaless structure.
Thats how I did it:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// set up a mongoose model and pass it using module.exports
module.exports = mongoose.model('Form', new Schema({}, { strict: false} ));