I'm new in the node.js world, but I'm trying to do a REST API with mongoDB and some javascript prototyping.
What is the best approach to have a model and the prototype object? Do i need to have the mongo schema definition in the same class of the prototype?
For example:
var Person = function (name) {
this.name = name;
}
Person.prototype.getSchema = function () { //To-do create mongo schema
}
Person.prototype.getName = function () {
return this.name;
}
Is that a good approach? Do I have to modify something?
I recommend to you starting with mongoose.
In mongoose would be something like this:
const mongoose = require('mongoose')
const Schema = mongoose.Schema
var userSchema = new Schema({
username: String,
password: String
})
userSchema.statics = {
getByName(name) {
return this.find({name})
.exec(function(err, user) {
console.log(user);
});
}
}
module.exports = mongoose.model('User', userSchema)
Then in your controller you can import the User model and use the model method.
Related
I'm testing a nodejs snippet to do iteration with my example mongodb collection users. But the query never worked. The full users collection are printed.
The standalone mongodb is setup in EKS cluster.
Why the query {name: "Baker one"} didn't work?
The code is:
const mongoose = require("mongoose");
const url = "mongodb://xxxxxx:27017/demo";
main().catch(error => console.error(error.stack));
async function main() {
// Connect to DB
const db = await mongoose.connect(url);
console.log("Database connected!");
const { Schema } = mongoose;
// Init Model
const Users = mongoose.model("Users", {}, "users");
const users = await Users.find({name: "Baker one"}).exec();
// Iterate
for await (const doc of users) {
console.log(doc);
console.log("users...");
}
console.log("about to close...");
db.disconnect();
}
The users collection:
The execution result:
$ node modify.js
Database connected!
{ _id: new ObjectId("610f512c52fa99dcd04aa743"), name: 'Baker one' }
users...
{ _id: new ObjectId("61193ed9b8af50d530576af6"), name: 'Bill S' }
users...
about to close...
This line could be the culprit (note that the schema has been defined with no fields like Joe pointed out in the comments).
const Users = mongoose.model("Users", {}, "users");
In this case, I had to add StrictQuery option in the Schema constructor to make it work, like so:
const userSchema = new Schema({}, { collection: "Users", strictQuery : false });
I'm having a trouble grasping a concept in Mongoose.
I'm using MongoDB atlas, got a cluster , a database and 2 collections.
users, characters.
Through a guide I've learned that a good way to write your stuff is to have a model (I use the naming schema) as a file, importing it into your Database module/class
and using it there to perform a query...
const mongoose = require("mongoose");
const process = require("./config.env");
db = () => {
return mongoose
.connect(process.env.URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: true,
})
.then((response) => {
console.log(`Connected to Databse : ${response.connection.host}`);
})
.catch((err) => {
console.log("DB_ERROR:", err);
process.exit(1);
});
};
module.exports = db;
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema({
username: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
});
const User = mongoose.model("User", UserSchema);
module.exports = User;
const User = require("../schemas/User");
const db = require("../config/db");
class Database {
constructor(db, collection) {
this.db = db;
this.collection = collection;
this.User = User;
}
connect() {
return db();
}
}
module.exports = Database;
one file to handle the db connection..another file as the User schema and a third file to handle every function i might use globally...
One thing I cannot wrap my mind around is
how is the findOne() function able to locate the collection I am using without me telling it what collection i want it to search in?
is it somehow translating the
const User = mongoose.model("User", UserSchema);
line and searching for "users" as well? I just can't understand the magic behind this...
what if I want to search specifically in the characters collection...?
Mongoose uses the model name, as passed when it was created: mongoose.model("User", UserSchema), converted to lower case and with an 's' appended.
For the model User it uses the collection users by default. You can change this by explicitly specifying the collection name in the schema.
create dynamically mongo collection in mongoose. I tried below code: suggest me please
function residenceModel(regionName){
const residenceSchema = new Schema({
key:String,
value:String
}, { strict: false });
return mongoose.model(
`residence_meta_${regionName}`,
residenceSchema,
`residence_meta_${regionName}`
);
}
console.log(residenceModel);
exports.ResidenceModel = residenceModel;
You can create dynamic model with this simple steps
create a file dynamicModel.js
const mongoose = require('mongoose')
//import mongoose from 'mongoose'
const Schema = mongoose.Schema
const dynamicModel = (regionName) => {
const residenceSchema = new Schema({
key:String,
value:String
}, { strict: false })
return mongoose.model(
`residence_meta_${regionName}`,
residenceSchema,
`residence_meta_${regionName}`
);
}
module.exports = { dynamicModel }
// export default { dynamicModel }
On file where you want to include or create model let's say app.js
// Please take care of path
const { dynamicModel } = require("./dynamicModel")
//import { dynamicModel } from "./dynamicModel";
.....
.....
// User this method to create model and use It
const countryModel = dynamicModel("country")
countryModel.create({ key:"country", value:"USA" });
Use this method multiple time, Give it a shot and let me know
I fixed this issue. below is the code. you guys can use it.
function createMetaCollection(regionName){
console.log(regionName);
var residenceSchema = new Schema({
region:String,
customer_type:String,
},{strict: false});
residenceSchema.plugin(autoIncrement.plugin,{model:'resident_meta_'+regionName,field:regionName+'id',startAt:1});
exports.Typeof_employment_meta = mongoose.model('resident_meta_'+regionName,residenceSchema,'resident_meta_'+regionName);
}
My model university.js
const mongoose = require('mongoose');
const UniversitySchema = mongoose.Schema({
worldranking:String,
countryranking:String,
universityname:String,
bachelorprogram:String,
masterprogram:String,
phdprogram:String,
country:String
},{collection:'us'});
const University =module.exports = mongoose.model('University',UniversitySchema);
My route.js
const express = require('express');
const router = express.Router();
const University = require('../models/university');
//retrieving data
//router.get('/universities',(req,res,next)=>{
// University.find(function(err,universities){
// if(err)
// {
// res.json(err);
//}
// res.json(universities);
//});
//});
router.get('/usa',function(req,res,next){
University.find()
.then(function(doc){
res.json({universities:doc});
});
});
module.exports= router;
How to implement multiple collections in this get() function? I put my collection name in the model. Please help me with a solution to call multiple collections in get() function.
Here is Example to use multiple collection names for one schema:
const coordinateSchema = new Schema({
lat: String,
longt: String,
name: String
}, {collection: 'WeatherCollection'});
const windSchema = new Schema({
windGust: String,
windDirection: String,
windSpeed: String
}, {collection: 'WeatherCollection'});
//Then define discriminator field for schemas:
const baseOptions = {
discriminatorKey: '__type',
collection: 'WeatherCollection'
};
//Define base model, then define other model objects based on this model:
const Base = mongoose.model('Base', new Schema({}, baseOptions));
const CoordinateModel = Base.discriminator('CoordinateModel', coordinateSchema);
const WindModel = Base.discriminator('WindModel', windSchema);
//Query normally and you get result of specific schema you are querying:
mongoose.model('CoordinateModel').find({}).then((a)=>console.log(a));
In Short,
In mongoose you can do something like this:
var users = mongoose.model('User', loginUserSchema, 'users');
var registerUser = mongoose.model('Registered', registerUserSchema, 'users');
This two schemas will save on the 'users' collection.
For more information you can refer to the documentation: http://mongoosejs.com/docs/api.html#index_Mongoose-model or you can see the following gist it might help.
Hope this may help you. You need to modify according to your requirements.
I have two models defined like this:
user.js
var sequelize = require('../database.js').sequelize,
Sequelize = require('../database.js').Sequelize,
userAttributes = require('./userAttributes.js');
User = sequelize.define('user', {},{
classMethods: {
createRider: function(params) {
var reqs = ['name', 'phone', 'fbprofile'],
values = [],
newUser;
reqs.forEach((req) => {
var value = params[req];
});
//Here I want to use the userAttributes-object.
return newUser;
}
}
});
module.exports = User;
userAttributes.js
var sequelize = require('../database.js').sequelize,
Sequelize = require('../database.js').Sequelize,
User = require('./user.js');
UserAttribute = sequelize.define('userAttributes', {
name: Sequelize.STRING,
value: Sequelize.STRING,
});
UserAttribute.belongsTo(User);
module.exports = UserAttribute;
in user User.addRider I want to add some records to UserAttributes, so I want to inclued that model in user. In userAttributes, I need to require Users to define it as a belongsTo. This doesn't seem to work. How can I solve this?
You can use a single file which imports all models and associates them after all models have been imported. This way, you do not need any circular references.
The second most popular answer in this question describes how to do it: How to organize a node app that uses sequelize?.