MongoDb relations not connected with other - javascript

I am writing a cook book in node.js. Im new to this language and mongoDB concept. I identify that I need to have a user who has favorite recipes nad in favorite recipes I am going to store recipes
My model look like that and something its wrong here
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
userSchema = new Schema({
name: String,
userId: {type: String, required: true},
favorites: [{
type: Schema.Types.ObjectId,
ref: 'Favorites',
}],
});
favoritesSchema = new Schema({
name: String,
id: {type: Schema.Types.ObjectId},
recipes: [{
type: Schema.Types.ObjectId,
ref: 'Recipes',
}],
startOfRecipe: {type: Date},
});
recipeSchema = new Schema({
name: {type: String, unique: true},
});
const User = mongoose.model('User', userSchema);
const Favorites = mongoose.model('Favorites', favoritesSchema);
const Recipes = mongoose.model('Recipes', recipeSchema);
module.exports = {User, Favorites, Recipes};
I wrote a function which looking for user and then store favorite recipe
addFav(fav, userId) {
return new Promise(function(resolve, reject) {
schema.User.findOne({userId: userId}, function(err, user) {
if (err || !user) {
} else {
schema.Favorites.create({
name: fav,
}, (err, result) => {
if (err) throw err;
console.log(result);
resolve('noResult');
});
resolve(user);
}
});
});
}
and it saves but if I call my user the array favorites is always empty
{ favorites: [],
_id: 5cb32867d2dfea0cadd79ecb,
name: 'Anna',
userId:
'AF322',
__v: 0 }
What am I doing wrong? Could someone help me please :)

Please check below code. I created subschema of favorites & recipes, get user details using userId and push favorites object into favorites field
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
userSchema = new Schema({
name: String,
userId: {type: String, required: true},
favorites: [favoritesSchema],
});
favoritesSchema = new Schema({
name: String,
id: {type: Schema.Types.ObjectId},
recipes: [recipeSchema],
startOfRecipe: {type: Date},
});
recipeSchema = new Schema({
name: {type: String, unique: true},
});
const User = mongoose.model('User', userSchema);
addFav(fav, userId) {
return Schema.User.update({_id:userId}, {$set:{$push:{favorites:fav}}})
}

Related

How to select two table (document) value at a time by user id in mongoose?

I am using NodeJs, ExpressJs with Mongodb and Mongoose. I want to select two document's value by user id.
I have three model User, Academic and Career. I have made a relation with Academic and Career schema by _id of User schema. I have saved some values in these documents. Now i want to select academic and career's document value by user id.
Model
// user model
const userSchema = new mongoose.Schema({
name: {type: String},
email: {type: String},
});
const user = mongoose.model('User', userSchema);
// academic model
const academicSchema = new mongoose.Schema({
academicLevel: {type: String},
passYear: {type: Number},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
});
const academic = mongoose.model('Academic', academicSchema);
// career model
const careerSchema = new mongoose.Schema({
jobTitle: {type: String},
company: {type: String},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
});
const career = mongoose.model('Career', careerSchema);
documents
// user documents
_id: objectId("5d0df6a4134d4d295ca9f212")
name: "John Doe"
email: "john#gmail.com"
_id: objectId("5d0e70a6c87ca528c0a79a0f")
name: "Mark Boucher"
email: "mark#gmail.com"
// academic documents
_id: objectId("5d60bc7188a8ef3648b8e8cf")
academicLevel: "Master"
passYear: "2018"
user: objectId("5d0e70a6c87ca528c0a79a0f")
_id: objectId("5d60d56f0cf9af32901cb2aa")
academicLevel: "Bachelor"
passYear: "2016"
user: objectId("5d0e70a6c87ca528c0a79a0f")
// career documents
_id: objectId("5d60bc1d88a8ef3648b8e8ce")
jobTitle: "Software Engineer"
company: "Daffodil Software Ltd."
user: objectId("5d0e70a6c87ca528c0a79a0f")
nodejs
router.get('/getInfoById', async (req, res) => {
const user = await User
.find(req.query.id)
.select()
res.send(user);
})
How to get values from two documents (academic and career) by user id. Thanks.
For what I've read in the docs, I think what you are looking for is something like so:
const career = await Career.find({ user: user._id});
const academics = await Academics.find({ user: user._id});
Or if you want to execute both queries at the same time:
const careerOperation = Career.find({ user: user._id});
const academicsOperation = Academics.find({ user: user._id});
const [
career,
academics
] = await Promise.all([career.exec(), academics.exec()]);
Hope to have helped!
Since Mongoose is used here: This can achieved using Populate. populate is pretty similar/analogues to what you would achieve via $lookup aggregation in pure mongo.
An alternative option: If you would adjust your schemas like this to really leverage Mongoose.
//user model
const userSchema = new mongoose.Schema({
name: { type: String },
email: { type: String },
career: {
type: Schema.Types.ObjectId,
ref: "Career"
},
academic: {
type: Schema.Types.ObjectId,
ref: "Academic"
}
});
//academics and career can be array of documents as well -if required
const user = mongoose.model("User", userSchema);
// academic model
const academicSchema = new mongoose.Schema({
academicLevel: { type: String },
passYear: { type: Number }
});
const academic = mongoose.model("Academic", academicSchema);
// career model
const careerSchema = new mongoose.Schema({
jobTitle: { type: String },
company: { type: String }
});
const career = mongoose.model("Career", careerSchema);
Populate query: To get user's academics and career docs
const user = await User.find({ _id: requestedUserId })
.populate("academic")
.populate("career")
.exec();
NOTE: requestedUserId is the user id that to be filtered upon.
This is the simplest query we can make for find user with given query Id
router.get('/getInfoById/:id', async (req, res) => {
const user = await User.aggregate([
{ $match: { _id: mongoose.Types.ObjectId(req.query.id) }},
{ $lookup: {
from: "career",
localField: "_id",
foreignField: "user",
as: "careers"
}},
{ $lookup: {
from: "academic",
localField: "_id",
foreignField: "user",
as: "academics"
}}
])
res.send(user);
});

findout a chat room by owner ids Mongoose

I am trying to find out a chat room with two owners (sender and receiver) from DB. if such a chat room is not there one has to be created with ids provided and a name
i am trying to create a chat app with user login and db storage.
//Mongoose Schema
const chatRoomSchema = new mongoose.Schema({
room:{
type: String,
trim:true,
required:true
},
owners:[{
owner:{
type:mongoose.Schema.Types.ObjectId,
required:true,
ref:'User'
}
}]
},{
timestamps:true
})
const ChatRoom = mongoose.model('Chatroom',chatRoomSchema)
//what i tried
const id1 = req.params.id1
const id2 = req.params.id2
let chatroom = ChatRoom.find({owners:{$all:[{owner:id1}, {owner:id2}]}})
if(!chatroom){
console.log('no chat room')
chatroom = new ChatRoom({room:'123', owners:[{owner:id1},{owner:id2}]})//creating a new chatroom
chatroom.save()
res.send(chatroom)
}
i am trying to find out a chat room with two owner ids. if there is no such chat room we have to create one with both ids as owners
You want an array of owner ids, not owner objects, so change:
owners:[{
owner:{
type:mongoose.Schema.Types.ObjectId,
required:true,
ref:'User'
}
}]
to
owners:[{
type:mongoose.Schema.Types.ObjectId,
required:true,
ref:'User'
}]
you can find room with 2 owners like:
var arr = ['5d6bd3b374068124c461975a', '5d6bd3b374068124c4619759']
ChatRoom.find({owners:{$all:arr}}, (err, room) =>{...}
full sample project:
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const init = false
mongoose.connect('mongodb://127.0.0.1/stackoverflow_play5')
//Mongoose Schema
const userSchema = new Schema({
username: String
})
const chatRoomSchema = new mongoose.Schema({
room:{
type: String,
trim:true,
required:true
},
owners:[{
type:mongoose.Schema.Types.ObjectId,
required:true,
ref:'User'
}]
},{
timestamps:true
})
const ChatRoom = mongoose.model('Chatroom',chatRoomSchema)
const User = mongoose.model('User',userSchema)
if(init){
User.insertMany([{username: 'yaya'}, {username: 'hoho'}, {username: 'mil'}], (err, users) => {
ChatRoom.insertMany([{room: 'r1', owners: [users[0]._id, users[1]._id]}], (err, chatrooms) => console.log('done.'))
})
}else{
//ChatRoom.find({}, (err, users)=>{console.log(users)})
var arr = ['5d6bdfe9c0d0af00ec68932c', '5d6bdfe9c0d0af00ec68932d']
ChatRoom.find({owners:{$all:arr}}, (err, room) =>{
console.log(room)
})
}
You can change room to be auto generated by mongoo, and instead of find then create if not found you can use findOneAndUpdate
const chatRoomSchema = new mongoose.Schema({
room:{
type: mongoose.Schema.Types.ObjectId,
auto: true
},
owners:[{
owner:{
type:mongoose.Schema.Types.ObjectId,
required:true,
ref:'User'
}
}]
},{
timestamps:true
})
const ChatRoom = mongoose.model('Chatroom',chatRoomSchema)
//what i tried
const id1 = req.params.id1
const id2 = req.params.id2
const options = { upsert: true, new: true, setDefaultsOnInsert: true };
let chatroom = ChatRoom.findOneAndUpdate(
{owners:{$all:[{owner:id1}, {owner:id2}]}},
{ owners:[{owner:id1},{owner:id2}] } ,
options, function(error, result) {
if (error) return;
// do something with the document
});

Mongoose + Mongodb User.update not working

What I am trying to do is create a new collection, and push that collection into a specific User.collections array. I have read many stackoverflow posts and they all say to use either User.update() or User.findOneAndUpdate(). I am have no luck with either. I can create a Collection and that is saved to mongo so I know I am indeed accessing the db. Here is my code, if any of you can help I would appreciate it.
User Schema
const mongoose = require('mongoose');
const { Schema } = mongoose;
const userSchema = new Schema({
googleID: String,
givenName: String,
familyName: String,
collections: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "collection"
}
]
});
mongoose.model('users', userSchema);
Collection Schema:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const collectionSchema = new Schema({
type: String,
name: String,
gamesCollected: [
{
id: Number
}
]
});
mongoose.model('collection', collectionSchema);
And my route:
router.get('/get_collection', (req, res) => {
const collection = new Collection({
type: 'SNES',
name: 'First SNES Collection',
gamesCollected: [{ id: 5353 }]
}).save();
User.update({googleID: req.user.googleID}, {$push: {collections: collection}});
});
Save is not a synchronous operation but asynchronous so you need to use the promise it returns and handle it and once it is complete then update the user model. Something among these lines:
router.get('/get_collection', async (req, res) => {
let collection = new Collection({
type: 'SNES',
name: 'First SNES Collection',
gamesCollected: [{ id: 5353 }]
})
await collection.save().exec();
await User.update(
{googleID: req.user.googleID},
{$push: {collections: collection._id}}
).exec();
});

Mongoose .save fails

I learning node.js & mongoDB & mongoose, from maybe a week or 2. The problem I have right now is, I'm trying to save to db via mongoose .save(), but it doesn't work as expected. I'm watching a tutorial, and it's 3 days old, so should be up to date, but I'm getting strange error.
mpromise (mongoose's default promise library) is deprecated” error when testing [duplicate]
I read, here on stackoverflow that I can just add:
mongoose.Promise = require('bluebird');
It will work, but the code doesn't even go to the .save function, and don't trow an error. I'm not sure where the problem is.
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
let connectionString = 'mongodb://localhost:27017/mongo2';
mongoose.createConnection(connectionString, (err) => {
if (err) {
console.log(err);
return;
}
let Student = mongoose.model('Student', {
firstName: {type: String, required: true},
lastName: {type: String, required: true},
age: {type: Number},
facultyNumber: {type: String, unique: true}
});
let me = new Student({
firstName: 'Who',
lastName: 'amI',
age: 20,
facultyNumber: '9374823104'
});
me.save().then((info) => {
console.log(info);
}).catch((error) => {
console.log(error);
});
});
Edit: The result is: Getting the DB created, the collection too, but not the object. Everything is empty.
Very likely the problem is that your model does not have a schema attached.
const { Schema } = require('mongoose');
const StudentSchema = new Schema({
firstName: {type: String, required: true},
lastName: {type: String, required: true},
age: {type: Number},
facultyNumber: {type: String, unique: true}
}};
let Student = mongoose.model('Student', StudentSchema);

Mongoose allowing duplicates with unique constraint added

I am trying to avoid duplicates from being saved in the system, and have implemented the model like so...
var mongoose = require('mongoose'),
ObjectId = mongoose.Schema.Types.ObjectId,
Schema = mongoose.Schema;
var User = require('../models/user.js');
var Stamp = new Schema({
name: {type: String, unique: true },
creatorId: {type: ObjectId, ref: 'User'},
dateAdded: {type: Date}
}, {collection: "stamps"});
Stamp.index({name: 'text'});
//to avoid duplicate names
Stamp.path('name').index({ unique: true });
module.exports = mongoose.model('Stamp', Stamp);
The code for saving the new stamp:
var new_stamp = new Stamp ({
name: stampname,
creatorId: creatorId,
dateAdded: dateAdded
});
new_stamp.save(function(err, results){
if(!err) {
console.log('stamp has been added to the db');
} else {
console.log("Error creating stamp " + err);
}
});
How do I stop from duplicates being saved?

Categories

Resources