mongoose find in subdocument with $and statement - node.js

I want to find and update only one object in my array of object, that I try to findAndUpdate:
So I want to find my document with correct name and password, and then find only one subdocument, that I want update/save into
logic:
roomModel.findOneAndUpdate({ $and: [{ name: req.body.roomName }, { password: req.body.roomPassword }], 'users.name': req.body.userName }, {
'$set': {
'users.$.latitude': req.body.latitude,
'users.$.longitude': req.body.longitude,
'users.$.updateDate': new Date()
}
})
.then((room) => {
// ...
})
roomModel:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = require('./user').userSchema;
var room = new Schema({
name: String,
password: String,
users: [userSchema]
});
module.exports.roomSchema = room;
module.exports.roomModel = mongoose.model('room', room);
userModel:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var user = new Schema({
name: String,
latitude: String,
longitude: String,
updateTime: Date
});
module.exports.userSchema = user;
module.exports.userModel = mongoose.model('user', user);
I don't exactly know how to perform that and search along with subdocument search

Related

insert to MongoDB array with axios, restAPI and nodeJS

I am trying to add an item to a MongoDB array with RESTAPI through Axios. I thought it would look similar to the push method but I have no idea how to do that.
my Model is of a person:
const Schema = mongoose.Schema;
const PersonSchema = new Schema({
name: String,
password: String,
friends: [],
missions: []
})
const personModel = mongoose.model('Person', PersonSchema);
I want to add a mission to the mission array of a person.
and for example, in order to add a new Person, I use NodeJS and API:
(api.js)
router.post('/api/people', (req, res) => {
const personToAdd = req.body;
const newPersonPost = new personModel(personToAdd);
newPersonPost.save((e) => {
if (e) {
console.log("error");
}
});
res.json({
msg: 'Received'
})
});
and in the client side I use Axios:
axios({
url: 'http://localhost:8080/api/people',
method: 'POST',
data: dataToUpdate
})
.then(() => {
console.log('axios sent info to server');
}).catch((e) => {
console.log('error' + e);
})
Thank you so much!
express
router.post('updating mission endpoint url', async (req, res) =>
try {
const query = { /* content */}; /* write a query to retrieve the concerned user by using a unique identifier */
let person = await personModel.findOne(query);
person.missions.push(req.body.mission);
personModel.save();
} catch (err) {
console.log(err);
}
});
client
In the client side you just have to put the mission you want to add in data like you did above with the right endpoint url and you should add a unique identifier for the user you want to add mission to.
[] will not assign array type to your variable.
Change your schema file with the following:
const Schema = mongoose.Schema;
const PersonSchema = new Schema({
name: { type: String },
password: { type: String },
friends: { type: Array },
missions: { type: Array }
})
Update the db model entity file with following
First method:
const Schema = mongoose.Schema;
const PersonSchema = new Schema({
name: String,
password: String,
friends: {type : Array},
missions: {type : Array}
})
const personModel = mongoose.model('Person', PersonSchema);
Second Method :
const Schema = mongoose.Schema;
const PersonSchema = new Schema({
name: String,
password: String,
friends: [{ type: String }],
missions: [{ type: String }]
})
const personModel = mongoose.model('Person', PersonSchema);
You can update the array object as per your requirements.
You just want to be using the $push update operator, very simple, like so:
db.collection.updateOne(
{
_id: user._id
},
{
"$push": {
"missions": {
mission: newMission
}
}
})
Mongo Playground

Invalid schema configuration: `model` is not a valid type within the array `characters`

I'm trying to create a schema subdocument but am getting the error listed above,
The schemas in question look like this
Schema casuing issues
const mongoose = require('mongoose');
const Schema = mongoose.Schema
const CharacterSchema = new Schema();
CharacterSchema.add({
name: {
type: String,
required: true
},
title: {
type: String
},
charcterClass: { // will be limited in form creation
type: String
},
level: {
type: Number
}
});
const Charcter = mongoose.model('User', CharacterSchema);
module.exports = Charcter;
Schema calling schema above
const mongoose = require ('mongoose');
const Schema = mongoose.Schema;
const {CharacterSchema} = require(__dirname +'/CharacterModel.js');
const UserSchema = new Schema()
UserSchema.add({
name: {
type: String,
required: true
} ,
characters: [CharacterSchema]
});
const User = mongoose.model('Character', UserSchema);
module.exports = User;
Try to do the import like this way
const {CharacterSchema} = require(__dirname +'/CharacterModel.js').schema;
Adding the .schema at the end.
This post is related to your issue, you will see the explanation there.
Embedding schemas is giving error
UserSchema :
const mongoose = require ('mongoose');
const Schema = mongoose.Schema;
const CharacterSchema = new Schema({
name: {
type: String,
required: true
},
title: {
type: String
},
charcterClass: {
type: String
},
level: {
type: Number
}
});
const UserSchema = new Schema({
name: {
type: String,
required: true
} ,
characters:{
type:[CharacterSchema]
}
});
const User = mongoose.model('User', UserSchema);
module.exports = User;

Mongoose Populate not populating the data

The following are two blocks of code, the first one is my Schema and the second one is my query. The Payment model is getting saved and it has the id referring to the user. Can I know where I am going wrong, is there any thing wrong with the fundamental ?
Here is my schema of User and Payment
User:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.Promise = global.Promise;
var paymentSchema = new Schema({
amount: Number,
user: {
type: Schema.Types.ObjectId,
ref: 'User'
}
});
var userSchema = new Schema({
email: String,
payment: {
type: Schema.Types.ObjectId,
ref: 'Payment'
}
});
module.exports = mongoose.model('User', userSchema);
module.exports = mongoose.model('Payment', paymentSchema);
Here is my query which I am using to populate using promise:
User.findOne({email: req.query.email})
.populate('payment')
.select('_id payment')
.then(function(user) {
res.json(user);
});

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
});
});

Mongoose populate not populating and how to give value to populate field

I'm using Mongodb and Nodejs.
I have two collections projects and users.
I want to retrieve name in the login collection based on the memberId i will give in the Project collection.I tried the code below, its populating as null.
My question is how to give values to memberId in projectModel in the frontEnd.Beacause it is of type of objectId.I want to pass value to memberId as "sam#gmail.com". Based on this, i want retrieve name from user schema.
Heremy schema :
UserSchema
'use strict';
var mongoose = require('mongoose'),
bcrypt = require('bcryptjs'),
crypto = require('../lib/crypto');
var userModel = function () {
var userSchema = mongoose.Schema({
name: String,
login: { type: String, unique: true }, //Ensure logins are unique.
password: String,
role: String
});
userSchema.pre('save', function (next) {
var user = this;
if (!user.isModified('password')) {
next();
return;
}
next();
});
userSchema.methods.passwordMatches = function (plainText) {
var user = this;
return bcrypt.compareSync(plainText, user.password);
};
return mongoose.model('User', userSchema);
};
ProjectSchema
'use strict';
var mongoose = require('mongoose'),
schema = mongoose.Schema;
var projectModel = function () {
var projectSchema = schema({
projectName: String,
projectNo: String,
startDate: String,
endDate: String,
releases:String,
sprintDuration:String,
sprintCount:String,
teamname: String,
teamno: String,
memberId :
{type: schema.Types.ObjectId, ref: 'users'},
story: [{
name: String,
creator: String,
date: String,
desc:String,
teamMember:String,
sprintNo: String,
sprintStartDate: String,
sprintEndDate: String,
status: String
}]
});
module.exports = new projectModel();
router.post('/home', function (req, res) {
var projectName = req.body.projectName && req.body.projectName.trim();
var projectNo = req.body.projectNo && req.body.projectNo.trim();
var memberId = req.body.memberId;
Project.
find({})
.populate('memberId')
.exec(function(err, people) {
if (err) return handleError(err);
console.log( people);
});

Resources