Nodejs Mongodb update multiple collections - node.js

In mongodb have two collections for now Event and Packages. So basically the model looks like this
Event Model
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const Schema = mongoose.Schema;
const bcrypt = require('bcrypt-nodejs');
const EventSchema = new Schema({
_id: mongoose.Schema.Types.ObjectId,
eventname: {
type: String,
required : true,
},
eventdesc: {
type: String,
required : true,
},
createdAt: {
type: Date,
default: Date.now
},
updatedAt: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('Event', EventSchema);
Package Model looks like this
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const Schema = mongoose.Schema;
const bcrypt = require('bcrypt-nodejs');
const PackageSchema = new Schema({
_id: mongoose.Schema.Types.ObjectId,
eventpackages: {
type: Object,
required : false,
},
event: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Event'
},
createdAt: {
type: Date,
default: Date.now
},
updatedAt: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('Package', PackageSchema);
Here I am trying to update an event so when the event will be updated the packages will be updated also. So in nodejs I have done like this
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
/* UPDATE EVENT */
router.put('/:id', function(req, res, next) {
upload(req, res, function(err) {
let EventData = {
eventname : req.body.eventname,
eventdesc : req.body.eventdesc,
}
let EventPackages = {
eventpackages : req.body.sections,
}
Event.findByIdAndUpdate(req.params.id, EventData, function (err, post) {
if (err) return next(err);
Package.findAndModify({
query: { event: req.params.id },
update: { $inc: { EventPackages } },
new: true,
upsert: true
})
res.json(post);
});
});
});
module.exports = router;
But its not working at all. If I will deleted the codes for package update it will work for events.
So can someone tell me how to make this work so that I can update multiple collections at a time.

you can try this,
var query = {
'event': req.params.id
};
var dataToUpdate = {
$set: {
///
}
};
Package.updateMany(query, datatoUpdate, function(err, result) {
if (err) return handleError(err);
return Promise.resolve(result);
});

Related

Node Js MongoDb Error "ERR_INVALID_ARG_TYPE"

i am beginner of node js and mongodb.when i tried to add the add via postman to mongodb i ran into the problem.
{
"code": "ERR_INVALID_ARG_TYPE"
}
what i tried so far i attached below.
routes
router.route('/user/getAll').get(userController.getDataConntrollerfn);
userController.js
var createUserControllerFn = async (req, res) =>
{
const userModelData = new userModel(req.body)
try
{
await userModelData.save()
res.status(201).send(userModel);
}
catch(error)
{
res.status(400).send(error);
}
}
userModel.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
name: {
type: String,
required: true
},
address: {
type: String,
required: true
},
phone: {
type: String,
required: true
}
});
module.exports = mongoose.model('employees', userSchema);

When making a POST request for a subdocument it comes back as undefined? mongoose, express

I'm trying a to make a post request to save new data to one of my subdocuments, but I'm getting an error when trying to access the subdocument in the function. It keeps coming back as undefined. How can I get a specific user by id and create and add new data the one it's subdocuments?
model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const ClassworkSchema = new Schema({
name: String,
time: Date,
todo: String,
isDone: false
});
const OutcomesSchema = new Schema({
name: String,
time: Date,
todo: String,
isDone: false,
isApproved: false
})
const MeetupSchema = new Schema({
name: String,
time: Date,
location: String,
attended: false
})
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
classwork:{type: [ClassworkSchema], default: []},
outcomes: [OutcomesSchema],
meetups: [MeetupSchema],
});
module.exports = User = mongoose.model('users', UserSchema);
controller
classworkRouter.post("/:userId/", (req, res) => {
User.findById(req.params.user_id, (err, user) => {
if (err) return err;
new_classwork = new classwork();
(new_classwork.name = req.body.name),
(new_classwork.date = req.body.date),
(new_classwork.todo = req.body.todo),
(new_classwork.isDone = req.body.isDone);
console.log(new_classwork);
user.classwork = {};
user.classwork.name = req.body.classwork.name;
user.classwork.todo = user.classwork.todo;
if (user.classwork === undefined) {
user.classwork.push(new_classwork);
} else {
user.classwork = [new_classwork];
}
user.save(function (err, data) {
if (err) res.send(err);
res.json({ message: "work added", data: data });
});
});
});
you can see the error in the terminal in the following phto:
in this part of code
new_classwork = new classwork()
you shoud defined the new_classwrok like this :
let new_classwork = new classwork()
and new classwork() is not defined, you must to require Model of classwork in controller..
in schema file export schemas like this :
const User = mongoose.model('users', UserSchema);
const Classwork = mongoose.model('Classwork', ClassworkSchema );
module.exports = {
User : User ,
Classwork : Classwork
}
in controller.js
const {User} = require('../models/certification');
const {Classwork } = require('../models/certification');
after require models you can use new Crosswork like this :
note: Classwork with uppercase character
let new_classwork = new Classwork()

Mongoose populate empty collection with other collections

I am trying to create a method for populating collection with a pre-defined Schema static method. I want it to grab all documents from 2 different collections and return them. It seems logical to me to create a separate Schema and return this.find().populate() callback as a result, but I can't get it to work...
Here are my Schemas:
dht.model.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
// Dht Schema from MongoDB
var DhtSchema = mongoose.Schema({
location: {
type: String,
required: true
},
reading: {
type: String,
required: true
}
}, {
timestamps: {
createdAt: 'created_at',
updatedAt: 'updated_at'
},
});
co2.model.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
// CO2 Schema from MongoDB
var CO2Schema = mongoose.Schema({
location: {
type: String,
required: true
},
reading: {
type: String,
required: true
}
}, {
timestamps: {
createdAt: 'created_at',
updatedAt: 'updated_at'
},
});
excel.model.js
This is the schema I want to populate dynamically, since new data is added to the database from MQTT middleware every 20 minutes and it has to return old and new results every time it has been invoked.
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
// Dht Schema from MongoDB
var ExcelSchema = mongoose.Schema({
co2: [{
type: Schema.ObjectId,
ref: 'co2'
}],
dht: [{
type: Schema.ObjectId,
ref: 'dhts'
}]
});
ExcelSchema.statics.showAll = function (cb) {
return this.find().populate('co2 dht').exec(function (err, cb) {
if (err) {
return err;
}
return cb;
});
};
module.exports = mongoose.model('merged_sensors', ExcelSchema);
When method is invoked within the API, it freezes and returns 504. My only assumption is, that it can't access the collections for some reason, but I am, most likely, wrong.
Update:
Here is a controller, which makes an API call for that Collection:
excel.controller.js
var Xls = require('./../models/excel.model'),
express = require("express"),
router = express.Router();
router.get("/all", function (req, res) {
Xls.showAll(function (err, results) {
if (err) throw err;
res.json(results);
})
});
module.exports = router;

Mongodb two collections aggregation

players schema:
var mongoose = require('mongoose'),Schema = mongoose.Schema;
var playerSchema = new mongoose.Schema({
name: String,
password: String,
country: [{ type: Schema.Types.ObjectId, ref: 'countries' }]
});
mongoose.model('players', playerSchema);
countries schema:
var mongoose = require('mongoose'),Schema = mongoose.Schema;
var countrySchema = Schema({
name: String,
isActive: Boolean
});
mongoose.model('countries', countrySchema);
And this is my node js find query:
router.route('/')
.get(function(req, res, next) {
mongoose.model('players').find().populate('country').exec(function (err, players) {
console.log(players);
if (err) {
return console.error(err);
} else {
res.format({
html: function(){
res.render('players/index', {
title: 'Players',
"players" : players
});
},
json: function(){
res.json(players);
}
});
}
});
});
I want the result set with countryId and name . But I got country is null.What to do ?

Mongoose one-to-many

can you explain me how to organize mongoose models to create one to many connections? It is needed keep separate collections.
suppose i have stores and items
//store.js
var mongoose = require('mongoose');
module.exports = mongoose.model('Store', {
name : String,
itemsinstore: [ String]
});
//item.js
var mongoose = require('mongoose');
module.exports = mongoose.model('Item', {
name : String,
storeforitem: [String]
});
Am i doing it in the right way?
And how to access pass data to arryas?
Here is the code yo enter name to item. But how to enter id to array of id's (itemsinstore)?
app.post('/api/stores', function(req, res) {
Store.create({
name: req.body.name,
}, function(err, store) {
if (err)
res.send(err);
});
})
You should use model reference and populate() method:
http://mongoosejs.com/docs/populate.html
Define your models:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var storeSchema = Schema({
name : String,
itemsInStore: [{ type: Schema.Types.ObjectId, ref: 'Item' }]
});
var Store = mongoose.model('Store', storeSchema);
var itemSchema = Schema({
name : String,
storeForItem: [{ type: Schema.Types.ObjectId, ref: 'Store' }]
});
var Item = mongoose.model('Item', itemSchema);
Save a new item into an existing store:
var item = new Item({name: 'Foo'});
item.save(function(err) {
store.itemsInStore.push(item);
store.save(function(err) {
// todo
});
});
Get items from a store
Store
.find({}) // all
.populate('itemsInStore')
.exec(function (err, stores) {
if (err) return handleError(err);
// Stores with items
});
You can do using the best practices with Virtuals.
Store.js
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const StoreSchema = new Schema({
name: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now
}
})
StoreSchema.virtual('items', {
ref: 'Item',
localField: '_id',
foreignField: 'storeId',
justOne: false // set true for one-to-one relationship
})
module.exports = mongoose.model('Store', StoreSchema)
Item.js
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const ItemSchema = new Schema({
storeId: {
type: Schema.Types.ObjectId,
required: true
},
name: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now
}
})
module.exports = mongoose.model('Item', ItemSchema)
StoreController.js
const Store = require('Store.js')
module.exports.getStore = (req, res) => {
const query = Store.findById(req.params.id).populate('items')
query.exec((err, store) => {
return res.status(200).json({ store, items: store.items })
})
}
Keep in mind that virtuals are not included in toJSON() output by default. If you want populate virtuals to show up when using functions that rely on JSON.stringify(), like Express' res.json() function, set the virtuals: true option on your schema's toJSON options.
// Set `virtuals: true` so `res.json()` works
const StoreSchema = new Schema({
name: String
}, { toJSON: { virtuals: true } });
Okay, this is how you define a dependancy:
var mongoose = require('mongoose');
module.exports = mongoose.model('Todo', {
name : String,
itemsinstore: [{ type: Schema.Types.ObjectId, ref: 'Item' }]
});
And make sure you have different names:
var mongoose = require('mongoose');
module.exports = mongoose.model('Item', {
name : String,
storeforitem: [String]
});
Keep an eye on Item in both cases.
And then you just want to pass the array of ObjectIDs in it. See more here: http://mongoosejs.com/docs/populate.html
Try this:
Store.findOne({_id:'5892b603986f7a419c1add07'})
.exec (function(err, store){
if(err) return res.send(err);
var item = new Item({name: 'Foo'});
item.save(function(err) {
store.itemsInStore.push(item);
store.save(function(err) {
// todo
});
});

Resources