How to update a object in mongodb using mongoose? - node.js

I have a Schema:
exports.participant = function(mongodb){
var participantSchema = new mongoose.Schema({
uniqueid: {type: String, unique: true},
channel: String,
conference: String,
calleridnum: String,
calleridname: String,
event: String,
status : { type: Boolean, default: 0 }
},{ collection: 'participants'});
var participant = mongodb.model('Participant', participantSchema);
return participant;
}
I have already tried how to update a object in mongodb via mongoose, but still it doesn't work for me.
I want to update status to 1
I am calling the update code here . .
the file location of my schema is: ../models/app.js
the file location of my update is: ../lib/update.js
This is my update code . .
var appInit = require('../app');
var logger = appInit.logger;
var basedir = appInit.basedir;
var connection = appInit.connection;
var mongodb = appInit.mongodb;
var handleAsteriskAmi = require(basedir+'/lib/handleasteriskami');
var asteriskAmi = new handleAsteriskAmi();
var handleHttpProc = require(basedir+'/lib/handlehttpproc');
var httpProc = new handleHttpProc();
function handleSocketio(){
this.init = function(io){
io.sockets.on('connection',function(socket){
if(socket){
logger.info("socket.io is connected");
}
socket.on('disconnect', function () {
logger.error("Socket.io is disconnected");
});
socket.on('action', function(data){
var result = JSON.parse(JSON.stringify(data));
asteriskAmi.listenActionConfbridge(result,function(response){
logger.info(JSON.stringify(response));
if(response.event=="originate"){
io.sockets.emit("response",response);
}
if(response.event=="confbridgemute" || response.event=="confbridgeunmute"){
io.sockets.emit("response",response);
mongodb.model("Participant").update(
{channel: response.channel},
{$set: {status: 1}}
);
}
if(response.event=="confbridgelock" || response.event=="confbridgeunlock"){
io.sockets.emit("response",response);
}
});
});
});

I believe you need to pass in a mongoose object in your participant function in ../models/app.js that you can then use to convert the participantSchema into a Model. Thus in your ../models/app.js, you can implement the participant function as
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
exports.participant = function(){
var participantSchema = new Schema({
uniqueid: {type: String, unique: true},
channel: String,
conference: String,
calleridnum: String,
calleridname: String,
event: String,
status : { type: Boolean, default: 0 }
},{ collection: 'participants'});
var participant = mongoose.model('Participant', participantSchema);
return participant;
}
Call the participant model in your ../lib/update.js:
var appInit = require('../app');
var Participant = appInit.participant();
Participant.update(
{channel: response.channel},
{$set: {status: 1}}
);

Related

"Item" schema is not found even i required that model.(mongoose,Node.js)

I am trying to run hook of 'remove' in label schema."Item.find is not a function" this is the error which I got.
But 'Item' schema is not found.This "require" works fine on other models.Here it is not working.
That error might be occurs in var Item = require('./Item');
This is "Label" schema.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Item = require('./Item');
var List = require('./List');
// created schema for Item
var labelSchema = new Schema({
label_title: {type: String},
color_id:{type: String, required: true},
created_at: Date,
updated_at: Date,
marked : { Boolean ,default:false },
_board: {type: Schema.Types.ObjectId, ref:'Board'}
});
//-----------------Hook--
labelSchema.post('remove',function(doc,next){
Label.remove({_id:this._id}).then(function(data){
console.log("successfuly removed label");
}).catch(function(error){console.log(error);
})
//-----remove label from all items
// console.log("ITEM", Item);
Item.find({},function(error,items){
items.forEach(function(item){
Item.findByIdAndUpdate(item._id,
{ "$pullAll": { "label" : [{ "label_id" : this._id }]} },function(error,result){
if(result)console.log("successfully removed");
else console.log("not removed");
})
})
})
});
var Label = mongoose.model('Label', labelSchema);
module.exports = Label;
What should I do?

Nodejs include Models

Im having problems to make my server.js use my models.
I do have other models with same structure, like for example:
var Post = mongoose.model('Post');
var Comment = mongoose.model('Comment');
but they works fine.. somehow.
But if If i try to use:
var Crime = mongoose.model('Crime');
i get:
throw new mongoose.Error.MissingSchemaError(name);
^
MissingSchemaError: Schema hasn't been registered for model "Crime".
if i switch to:
var Crime = require('./models/Crime');
or
var Crime = require('./models/Crime.js');
i get the response:
Cannot find module './models/Crime'
Crime model code:
var mongoose = require('mongoose');
var CrimeSchema = new mongoose.Schema({
username: {type: String, lowercase: true, unique: true},
time: String,
salt: String
});
CrimeSchema.methods.performCrime = function(pass) {
/*var deferred = $q.defer();
deferred.notify('loading....');
deferred.reject('Greeting is not allowed.');
return deferred.promise;
*/
return 22;
};
mongoose.model('Crime', CrimeSchema);
EDIT
example of working model:
var Post = mongoose.model('Post');
and post.js model
var mongoose = require('mongoose');
var PostSchema = new mongoose.Schema({
title: String,
link: String,
upvotes: {type: Number, default: 0},
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]
});
PostSchema.methods.upvote = function(cb) {
this.upvotes += 1;
this.save(cb);
};
PostSchema.methods.downvote = function (cb) {
this.upvotes -= 1;
this.save(cb);
};
mongoose.model('Post', PostSchema);
You forgot to export the module at the end.
var Crime = mongoose.model('Crime', CrimeSchema);
module.exports = Crime;

TypeError object is not a function

I'm developing an application in node.js with MongoDB
I have to files:
product.js and displaycost.js
this is product .js:
var mongoose = require('mongoose');
var Category = require('./category');
var productSchema = {
name:{type: String, require: true},
//Pictures mus start with "http://"
pictures:[{type:String, match: /^http:\/\//i}],
price:{
amount:{type: Number, required: true},
//ONly 3 supported currencies for now
currency:{
type: String,
enum:['USD','EUR','GBP'],
required: true
}
},
category: Category.categorySchema
};
var schema = new mongoose.Schema(productSchema);
var currencySymbols ={
'USD': '$',
'EUR':'€',
'GBP':'£'
};
/*
*
*/
schema.virtual('displayPrice').get(function(){
return currencySymbols[this.price.currency] +
'' + this.price.amount;
});
schema.set('toObject', {virtuals:true});
schema.set('toJSON', {virtuals:true});
module.exports = schema;
What I need is create a record with "productSchema"
I tried with this:
var Product = require('./product.js');
var p = new Product({
name: 'test',
price:{
amount : 5,
currency: 'USD'
},
category: {
name: 'test'
}
});
console.log(p.displayPrice); // "$5"
p.price.amount = 20;
console.log(p.displayPrice); //" $20"
//{... "displayPrice: "$20",...}
console.log(JSON.stringify(p));
var obj = p.toObject();
But when I run the displaycost.js throw me an error at the word "new"
and writes "TypeError: object is not a function"
I don't know why is happening that. Thank you.
you missing export mongoose model with model name.
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
Category = require('./category');
var productSchema = new Schema({
name: {type: String, require: true},
pictures: [{type: String, match: /^http:\/\//i}],
price: {
amount: {type: Number, required: true},
currency: {
type: String,
enum: ['USD', 'EUR', 'GBP'],
required: true
}
},
category: Category
});
var currencySymbols = {
'USD': '$',
'EUR': '€',
'GBP': '£'
};
productSchema.virtual('displayPrice').get(function () {
return currencySymbols[this.price.currency] +
'' + this.price.amount;
});
productSchema.set('toObject', {virtuals: true});
productSchema.set('toJSON', {virtuals: true});
module.exports = mongoose.model('Product', productSchema);
"new" can only be called on a function. not an object.
In program.js you are creating a new instance of the mongoose schema.
var schema = new mongoose.Schema(productSchema);
... more code ...
return schema;
In your other js file you require product. At this point in time product.js has returned an object to you. A new mongoose schema. It is an object which you are refering to as Product.
You then try to create a new instance of it by calling new on the product OBJECT. New cannot be called on an object literal. It can only be called on a function.
I don't believe you need to make a new instance of schema within product.js, just return the function that creates the schema. Then call new on it when you require it like you are in your second file.

Create a new document using MEAN mongoose

i'm new to mongoose and mongodb, i'm trying to create a new document inside my collection.
I'm able to update existing one or get all the document from the collection.
I need to create a new document based on the collection (I have a single collection now). - createMoment function.
var mongoose = require('mongoose');
var db = mongoose.connect('mongodb://url and pass');
var usersSchema = require('./users_schema').usersSchema;
mongoose.model('usersM', usersSchema);
var usersAction;
mongoose.connection.once('open',function(){
var Users = this.model('usersM');
var query = Users.find();
query.where('userId');
query.exec(function(err, docs){
usersAction = docs;
console.log("docs: " + usersAction);
return usersAction;
});
});
exports.getData = function(){
return usersAction;
};
exports.createMoment = function(_fn, _ln, _conc,_lan,_lat,cb){
var Users = mongoose.model('usersM');
console.log("createMoment Called");
Users.insertOne({
'leadRank':1,
'adminApproval':true,
'userFname':_fn,
'userLname':_ln,
"conclusion":_conc,
'tentCoor':{'latitude' : _lat, 'longitude' : _lan}
}, null, function(err, result) {
assert.equal(err, null);
console.log("Inserted a document into the users collection.");
cb(result);
});
};
My schema:
I'm not passing some of the fields yet
var mongoose = require('mongoose');
var schema = mongoose.Schema;
var usersSchema = new schema({
campName: {type:String, required:true},
centerCoor: [{
latitude:{type:Number},
longitude:{type:Number}
}],
zoom: {type:String},
users: [{
leadRank: {type:Number},
adminApproval: Boolean,
userFname: {type:String, required:true},
userLname: {type:String, required:true},
conclusion: {type:String},
tentCoor: [{
latitude:{type:Number},
longitude:{type:Number}
}]
}]
}, {collection: 'camps'});
exports.usersSchema = usersSchema;

NodeJS Mongo - Mongoose - Dynamic collection name

So, I want to create a client side based paritioning schema, where I set the collection name as function(), my pseudo code is something like that:
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
var ConvForUserSchema = new Schema({
user_id: Number,
conv_hash: String,
archived: Boolean,
unread: Boolean
}, function CollectionName() {
return (this.user_id % 10000);
});
Is this in any way possible through moongose such that both read and writes will work as expected?
Hello you just need to declare schema model with your dinamically name, like this:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// our schema
function dynamicSchema(prefix){
var addressSchema = new Schema({
dir : {type : String, required : true}, //los 2 nombres delimitados por coma (,) ej. Alberto,Andres
city : {type : String, required: true}, //la misma estructura que para los nombres ej. Acosta, Arteta
postal : {type : Number, required : true},
_home_type : {type : Schema.Types.ObjectId, required : true, ref : prefix + '.home_type'},
state : {type : String, required : true},
telefono : String,
registered : {type : Date, default: Date.now }
});
return mongoose.model(prefix + '.address', addressSchema);
}
//no we export dynamicSchema function
module.exports = dynamicSchema;
so in your code anywhere you can do this:
var userAdress = require('address.js')(id_user);
var usrAdrs1 = new userAddress({...});
userAdrs1.save();
Now go to your mongo shell & list collections (use mydb then show collections), you will see a new collection for address with uid prefix. In this way mongoose will create a new one collection address for each different user uid.
Use the function to get the model dynamically.
/*
* Define Schemas as you used to
*/
const ConvForUserSchema = new Schema({
user_id: Number,
conv_hash: String,
archived: Boolean,
unread: Boolean
},{
versionKey : false,
strict: false
});
/*
* Define the dynamic function
*/
const models = {};
const getModel = (collectionName) => {
if( !(collectionName in models) ){
models[collectionName] = connection.model(
collectionName, ConvForUserSchema, collectionName
);
}
return models[collectionName];
};
Then get the dynamic model using the function
const result = getModel("YourCollectionName").findOne({})
Collection name logic is hard coded all over the Moongose codebase such that client side partitioning is just not possible as things stands now.
My solution was to work directly with the mongo driver -
https://github.com/mongodb/node-mongodb-native
This proved great, the flexibility working with the driver directly allows for everything required and the Moongose overhead does not seem to add much in any case.
Implemented:
//Require Mongoose
const mongoose = require('mongoose');
const moment = require('moment');
//Define a schema
const Schema = mongoose.Schema;
const EntranceModelSchema = new Schema({
name: String,
birthday: Date,
gender: String,
phoneNumber: {type: String, require: true},
email: String,
address: String,
addressReference: String,
addressLatitude: {type: Number, require: true},
addressLongitude: {type: Number, require: true},
vehicleReference: String,
date: Date
});
//Export function to create "SomeModel" model class
module.exports = function(){
let dateSuffix = moment().format('MMMDoYYYY');
const collectionName = `Entrance${dateSuffix}`;
return mongoose.model(collectionName, EntranceModelSchema);
};
Gomosoft's solution works. It needs some amends but the idea works nicely.
The above solution works only the first time. If you are trying to send a second request to the same collection, it will throw an error for trying to overwrite the model that is already defined. So I had to tweak it as follows:
var Rating = require('./app/models/rating');
var myRating;
router.route('/ratings/:user_id')
.post(function(req,res){
var user_id = req.params.user_id;
if(myRating == undefined){
myRating = Rating(user_id);
}
...
rating.save(...);
});
Because I'm checking if myRating is undefined, it will create this reference only once. So no errors will occur.
Hope this helps.
I am adding to the answer by Javier Gomez, to give a solution to Exis Zang's "OverwriteModelError: Cannot overwrite xxx model once compiled" problem. The Schema model file can store an array of the dynamic models based on the Singleton pattern. If that model already exists return it, otherwise create it with new, store it and return it:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const Addresses = {}
// our schema
function DynamicSchema(prefix){
var addressSchema = new Schema({
dir : {type : String, required : true}, //los 2 nombres delimitados por coma (,) ej. Alberto,Andres
city : {type : String, required: true}, //la misma estructura que para los nombres ej. Acosta, Arteta
postal : {type : Number, required : true},
_home_type : {type : Schema.Types.ObjectId, required : true, ref : prefix + '.home_type'},
state : {type : String, required : true},
telefono : String,
registered : {type : Date, default: Date.now }
});
return mongoose.model(prefix + '.address', addressSchema);
}
// this function will store the model in the Addresses object
// on subsequent calls, if it exists, it will return it from the array
function getAddressModel(prefix) {
if (!Addresses[prefix]) {
Addresses[prefix] = new DynamicSchema(prefix)
}
return Addresses[prefix]
}
//now we export getAddressModel function
module.exports = getAddressModel;
To Create a dynamic collection follow the below steps,
const mongoose = require('mongoose');
function createCompanyDynamicSchema(prefix) {
let collectionName = prefix + '_company';
companySchema = new mongoose.Schema(
{
name: { type: String },
enabled: { type: Number, default: 1 },
},
{ timestamps: true },
{ versionKey: false },
{ strict: false }
);
collectionName = mongoose.model(collectionName, companySchema);
return collectionName;
}
module.exports = { createCompanyDynamicSchema };
To call this method from any file,
let companySchema = require('./schema');
_this.createCompany = function () {
return new Promise(async (resolve, reject) => {
let companyCollection = companySchema.createCompanyDynamicSchema('IO');
let addr = new companyCollection({ first_name: 'test' });
addr.save();
});
};
To query from dynamically created collection,
_this.getCompany = function () {
return new Promise(async (resolve, reject) => {
let companyCollection = companySchema.createCompanyDynamicSchema('IO');
let data = await companyCollection.model('IO_users').find();
console.log(data);
});
};

Resources