Node.js - Create Relationships with Mongoose from different file - node.js

I have two Schemas Products and Users in different files. Products are belong to User and User have many Product
The Problem is, I have try to use Populate but somehow it return not what I expected.
here is my Schema for Product on models products.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var users = require('../models/users');
var Product = mongoose.Schema({
user_id : {type: String, required: true },
category_id : {type: String, default: null},
title : {type: String, required: true },
content : {type: String, default : "" },
pictureUrls : Array,
counter : {type : Number, default : 0},,
lowercaseTitle : {type: String, default : null },
_user : { type: Schema.Types.ObjectId, ref: users.User }
});
Product.set('toObject', {
getters: true,
virtuals: true
});
module.exports = mongoose.model('Product', Product)
and this is my Schema for User on models users.js
var mongoose = require('mongoose');
var User = mongoose.Schema({
firstName : {type: String, default: "" },
lastName : {type: String, default: "" },
username : {type: String, required: true },
email : {type: String, required: true },
password : {type: String, default: "" },
bio : {type: String, default: "" },
website : {type: String, default: "" },
phone : {type: String, default: "" },
gender : {type: String, default: "" },
birthDate : {type: Date, default: null },
avatarUrl : {type: String, default: "" },
verified : {type : Boolean, default : false}
});
User.set('toObject', {
getters: true,
virtuals: true
});
module.exports = mongoose.model('User', User);
currently I am using method find by calling each Models
User.findOne({"sessionToken" : bearerHeader}, function (err, user){
Product.find({"user_id" : user._id}, function (err, products){
console.log(products);
});
});
but it takes time and became problem if there related to another models.
I'm calling populte with this
Product.findOne({}).populate('_user').exec(function(err, p){
console.log(p);
});
but attribute _user was not set and undefined
any help?
Thanks

Related

Is there any thing similar to mongo.model(); in DynamoDB...?

I want to create Dynamo db tables in node.js script.
In short i want dynamo-db code equivalent to following:
var mongo = require('mongoose');
var MongoDB = mongo.connect('mongodb://localhost:27017/test').connection;
MongoDB.on('error', function(err) { console.log(err.message); });
MongoDB.once('open', function() {
console.log("DynamoDB connection open");
});
var userschema = mongo.Schema({
name: String,
nickname: {type: String,default: ''},
email: String,
phone: String,
type: String,
port : String,
deviceRegId: {type: String,default: ''},
assignFlag: Number,
created: {type: Date,default: Date.now} ,
lastmsg : {type: String,default: ''} ,
lasttime : {type: Date,default: Date.now} ,
loginStatus : {type: Boolean,default: false} ,
isOnline : {type: Boolean,default: false} ,
chats: [{
from: String,
msgfrom: Number,
name: String,
msg: String,
date: {type: Date, default: Date.now},
flag: Number
}]
});
var agent = mongo.model('naveen', userschema);
exports.mongo = mongo;
exports.agent = agent;
I am trying to search similar Dynamo function, but could not find any. Any help would be of great use.
Here is the sample code to create the table if not present and create an item on it with default values.
Please note that you can't have empty value for an attribute on DynamoDB. For example, the nickname can't be set as empty string by default.
For any attribute, if you set an empty value and try to insert the data, DynamoDB will throw a validation exception.
So, default can't be empty string.
Code:-
var dynamoose = require('dynamoose');
dynamoose.AWS.config.update({
accessKeyId: 'AKID',
secretAccessKey: 'SECRET',
region: 'us-east-1'
});
dynamoose.local();
var Schema = dynamoose.Schema;
var userSchema = new Schema({
name: {
type: String,
hashKey: true
},
nickname: String,
email: String,
phone: String,
type: String,
port: String,
deviceRegId: String,
assignFlag: Number,
created: { type: Date, default: Date.now },
lastmsg: { type: String },
lasttime: { type: Date, default: Date.now },
loginStatus: { type: Boolean, default: false },
isOnline: { type: Boolean, default: false },
chats: [{
from: String,
msgfrom: Number,
name: String,
msg: String,
date: { type: Date, default: Date.now },
flag: Number
}]
},
{
throughput: { read: 15, write: 5 }
});
var Table = dynamoose.Table;
var UserDetails = dynamoose.model('UserDetails', userSchema);
var user1 = new UserDetails({ name: 'John' });
user1.save(function (err) {
if (err) { return console.log(err); }
console.log('Added a new item');
});
Sample item created:-
Date value is stored as Number.

Mongoose dup key

I'm getting a duplicate key error and not sure why.
I have the following schema:
var walletSchema = mongoose.Schema({
currencyName : {type : String, required : true, unique : true},
amount : {type : Number, default : 0}
}, {strict : false});
// define the schema for our user model
var userSchema = mongoose.Schema({
local : {
username : { type: String, required: true, unique: true },
password : { type: String, required: true, unique : true },
email : { type: String, required: true, unique: true },
country : { type: String, required: true },
inventory : {
food : { type : Number, default : 0},
energyDrinks : { type : Number, default : 0 }
},
wallet : [walletSchema],
lastAttackedAt : { type: Date, default: Date.now },
lastJobChange : {type: Date, default: '03/30/1988' },
lastWorked : {type: Date},
referredBy : {type : String, default : 'Admin'},
energy : { type: Number, default: 100 },
energyUpdatedAt : { type : Date, default: Date.now },
resetPasswordToken: String,
resetPasswordExpires: Date
}
},{timestamps : true});
I create a new user with this code :
...
newUser.local.username = capitalizeUser(username);
newUser.local.password = newUser.generateHash(password);
newUser.local.email = req.body.email;
newUser.local.country = req.body.country;
newUser.local.wallet.push({
// Create the default currencies
currencyName: 'Euro',
}, {
currencyName: 'Gold',
}, {
currencyName: result.countryCurrency
}
);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
Everything works fine for the first user however if I try to make another user I get MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index: xyz.users.$local.wallet.currencyName_1 dup key: { : "Euro" }.
Why is this happening, doesn't each user has it's own wallet? How should I handle it, keep in mind that there are about ~230 currencies available for each user.
currencyName : {type : String, required : true}
Remove unique from there and you will be good to go. Mongo checks unique keys for collection. In your case walletSchema collection will have a lot of same values so that's why it's gives error.
As your currencyName has been set unique so it has to be different for each user you save. In fact you with this schema you won't even be able to have two users from the same country.
So to avoid this you need to remove the unique keyword from you schema and it is done. It then looks something like this.
var walletSchema = mongoose.Schema({
currencyName : {type : String, required : true},
amount : {type : Number, default : 0}
}, {strict : false});

Mongoose Populate Method is not populating value

I have two mongoose schema as following
var ServiceSubType = new Schema({
displaySubTypeName : String,
subTypeDescription : String,
status : { type: String, default: Constants.ACTIVE },
lastUpdatedOn : Date,
createdOn : { type: Date, default: Date.now }
} , { collection: 'SERVICE_SUB_TYPES' });
and
var ServiceType = new Schema({
displayName : String,
description : String,
status : { type: String, default: Constants.ACTIVE },
lastUpdatedOn : Date,
serviceSubTypeId : {type: Schema.Types.ObjectId, ref: 'ServiceSubType', index: true},
createdBy : { type: Schema.Types.ObjectId, ref: 'SystemUser', index: true },
createdOn : { type: Date, default: Date.now }
} , { collection: 'SERVICE_TYPES' });
I have populated Type Object as below
module.exports.addNewServiceType = function(serviceType_obj, callback) {
serviceType_obj.save(serviceType_obj,callback);
}
Now I am trying to populate ServiceSubType document and then at the same time trying to populate "serviceSubTypeId" of ServiceType object referenced to ServiceSubType created.
Here is my piece of code for the same purpose.
module.exports.addServiceSubType = function(serviceTypeObjId, serviceSubType_obj, callback) {
serviceSubType_obj.save(serviceSubType_obj, function (error, serviceSubType) {
});
serviceSchema.ServiceType.findById(serviceTypeObjId, function (err, serviceType) {
var opts = { path: 'serviceSubTypeId'};
serviceSchema.ServiceType.populate(serviceType, opts, function (err, user) {
console.log(serviceType);
});
}).exec(callback);
}
But it is not workign and not populating any value in Existing SubType object.
I admit my approach could be very wrong as I am very new in this technology. Appreciate any kind of help to run this piece of code as expected.
Thanks
Ajoy
I think your ref should be the same setting as the collection on the object
serviceSubTypeId : {
type: Schema.Types.ObjectId,
ref: 'SERVICE_SUB_TYPES', <==== your collection type goes here
index: true
},
Mongoose doesn't know anything about your JavaScript object types. Instead, it tracks things based on the collection name that you provide (or that it generates).
update based on comments below
I have some example code that I wrote a while back, and it looks like I'm letting Mongoose generate the collection name for me. However, I am supplying a name to the mogoose.model() call, when registering my type for a collection.
For example, I have a Post type and a User type. The Post contains an author which is a reference to the User.
It looks like this:
// post
// ----
var PostSchema = new mongoose.Schema({
date: {type: Date, required: true, default: Date.now},
title: {type: String, required: true},
content: {type: String, required: true},
author: {
type: SchemaTypes.ObjectId,
ref: "user"
},
comments: [CommentSchema]
});
var Post = mongoose.model("blog", PostSchema);
// user
// ----
var UserSchema = mongoose.Schema({
firstName: {type: String},
lastName: {type: String},
username: {type: String, required: true, index: {unique: true}},
email: {type: String, required: true},
password: {type: String, required: true},
url: {
type: mongoose.Schema.Types.ObjectId,
ref: "url"
}
});
User = mongoose.model("user", UserSchema);
In this example code, I'm setting the ref to "user" because I am registering my model as "user" down below, in the mongoose.model method call.
Are you registering your models using mongoose.model and supplying a name? if so, use that name.

Mongoose subdocument not created in mongoDB but added to parent array

I have a method to update the commerce information. There is the possibility to add Workdays to the commerce by sending them in the request body.
There following code works fine except that the workdays are not created in mongoDB. They are only saved in the Commerce document (as an array od ids) but the Collection called "workday" is not createdin mongoDB. Why it's not created?
if(req.body.workdays){
var workdays = req.body.workdays;
var lunch = req.body.lunch.split("_");
commerce.workdays=[];
for(var i =0, size=workdays.length; i<size; i++ ){
var item=new Workday();
item.dayOfWeek = workdays[i];
item.owner=commerce._id;
var range = new Range();
range.initial = lunch[0];
range.end = lunch[1];
range.workday = item;
item.ranges.push(range);
commerce.workdays.push(item);
}
}
commerce.save(function(err) {
if(!err) {
log.debug('Updated');
res.status(200).send(commerce);
} else {
errorHandler.processError(err, res, log);
}
});
here are the models:
var CommerceSchema = new Schema({
// Common fields.
createdAt : {type : Date, default : Date.now},
location: [Number, Number],
photos: [{type : Schema.Types.ObjectId, ref : 'Photo'}],
name: { type: String},
address: { type: String},
email: { type: String, default: "-"},
workdays: [{type : Schema.Types.ObjectId, ref : 'Workday'}],
description: { type: String, default: "-"},
phone: { type: Number},
user: {type : String, ref : 'User'},
type: [{ type: Number, default: 0}]
});
var WorkdaySchema = new Schema({
dayOfWeek: { type: Number},
owner: {type : String},
ranges: [{type : Schema.Types.ObjectId, ref : 'Range'}],
createdAt : {type : Date, default : Date.now}
});
var RangeSchema = new Schema({
initial: { type: Number},
end: { type: Number},
workday: {type : String, ref : 'Workday'}
});
"workdays" is expecting Mongo ObjectIds. You have to save the individual Workdays first, and then you can add their Ids (_id) to the workdays Array.

Mongoose Sorting

I have a problem with displaying data with sorting. Here is my query,
Activity.find({"user_id": sesUser._id}, {}, {offset: 0, limit : 5, sort:{createdAt:1}}, function (e,a){
...
});
I have data about 252 length, and my latest data is 9 June 2015. If i use this query i only get data from 5 June 2015/ last week data and not get the latest data, but if i not using sorting, the latest data is appear.
I have used this query below but turns out the result is same.
Activity.find({"user_id" : sesUser._id}).sort("createdAt").exec(function(err,a){
...
});
Any help? I'm using Mongoose v3
-- edited --
This is my Activity Schema / Model
var mongoose = require('mongoose');
var Activity = mongoose.Schema({
sender_id : {type: String, required: true },
user_id : {type: String, required: true },
product_id : {type: String, default : "" },
type : {type: String, required: true },
createdAt : {type: String, default : new Date()}
});
module.exports = mongoose.model('Activity', Activity);
`createdAt : {type: Date, default : new Date()}`
Type Date not string man
It will automatically create the createdAt and updatedAt
var options={
timestamps: true
}
var Activity = mongoose.Schema({
sender_id : {type: String, required: true },
user_id : {type: String, required: true },
product_id : {type: String, default : "" },
type : {type: String, required: true }
},options);

Resources