Referencing another collection Mongoose (MONGO) - mongodb

If i have two Schema's as follows;
const userSchema = new mongoose.Schema({
telegramId: Number,
username: String,
balance: { type: Number, default: 0 },
totalTopUp: { type: Number, default: 0 },
totalRefunds: { type: Number, default: 0 },
totalOrders: { type: Number, default: 0 },
joined: Date,
});
const orderSchema = new mongoose.Schema({
orderId: String,
cardId: String,
userId: Number,
refunded: { type: Boolean, default: false },
baseId: String,
price: Number,
date: Date,
});
Where telegramId in userSchema and userId in orderSchema will match when a user makes an order, is it possible to have totalOrders in userSchema automatically update via some sort of referencing. Or will updates to totalOrders need to be made via code.

you can use post('save') middleware over orderSchema, on each new document you can increase the total orders.
https://mongoosejs.com/docs/api.html#schema_Schema-post

Related

How create nested mongoDb schema in mongoose?

i'm trying to design mongoose shema for users cleaner and customer, they have some common fields e.g. name, but also have extra (different fields) client(rating) and customer number. I'm not sure that my design is good.
I've created separate userSchema for customer and cleaner, and created separate address schema.
// User Schema
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
}
});
// AddressSchema
const AddressSchema = new mongoose.Schema({
city: {
type: String,
required: true
},
street: {
type: String,
required: true
}
});
// CustomerSchema
const CustomerSchema= new mongoose.Schema({
name: UserSchema,
address: AddressSchema
});
// CleanerSchema
const CleanerSchema= new mongoose.Schema({
name: UserSchema,
rating: {
type: Number,
required: true
}
});
My schema doesn't work. Could you give best practice example for my schema?
This is how I would define your Customer and Cleaner schemas. I don't think it's necessary to create the separate name and address schemas.
const CustomerSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
address: {
city: {
type: String,
required: true
},
street: {
type: String,
required: true
}
}
});
const CleanerSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
rating: {
type: Number,
required: true
}
});

Conditional query mongo db after populate not returning data

I am new in mongo and node and I am facing a problem in filtering.
I have a customer schema and wallet schema. When I am inserting a new
customer it is populating a wallet for that customer. Schema of this
two model is below.
Customer.model.js
var Schema = mongoose.Schema;
const Genders = Object.freeze({
Male: 'male',
Female: 'female',
Other: 'other',
});
var CustomerSchema = new Schema({
reg_date: { type: Date, default: Date.now },
first_name: String,
last_name: String,
gender: {
type: String,
enum: Object.values(Genders),
},
wallet_balance: { type: Number, default: 0 },
status:{type:Boolean,default:true},
wallet:{type:mongoose.Schema.Types.ObjectId,ref:'Wallet'},
customer_rank: String
});
module.exports = mongoose.model('Customer', CustomerSchema);
Wallet.model.js
var Schema = mongoose.Schema;
var TransactionSchema = new Schema({
reason: String,
deposit_by: Number,
transaction_type: String,
transacted_balnace:Number
})
var WalletSchema = new Schema({
user_id:String,
transaction_log: [TransactionSchema],
balance: { type: Number, default: 0 },
created_at: { type: Date, default: Date.now },
updated_at: { type: Date, default: Date.now }
});
WalletSchema.plugin(uniqueValidator);
module.exports = mongoose.model('Wallet', WalletSchema);
I want to get customer details on basis of reason.
So, the code is below.
CustomerModel.find({}, { "password": 0 }).populate({
path: 'wallet',
match: { reason: { $in: [ "service charge" ] } },
select: 'transaction_log'
}).exec().then(data => {
if (data) {
res.status(200).send({ status: true, data: data })
}
else {
res.send({ status: false, data: [] })
}
})
It is not returning the wallet, But if I remove the match property it
is working fine.It will be very helpful if I get a solution. Thanks
in advance.

How do you change a fieldName via mongoose method + change it in schema?

I have a schema like this:
const StorySchema = new Schema({
authorId: String,
title: String,
longUrl: String,
shortUrl: String,
comment: String,
category: String,
author: String,
date: { type: Date, default: Date.now, index: true },
votes: { type: Number, default: 1, index: true },
});
I want to change the votes field on the schema to be called votesCount and at the same time I want to actually change the schema.
Would I just do these in the same file?
const StorySchema = new Schema({
authorId: String,
title: String,
longUrl: String,
shortUrl: String,
comment: String,
category: String,
author: String,
date: { type: Date, default: Date.now, index: true },
votesCount: { type: Number, default: 1, index: true },
});
const StoryModel = mongoose.model('story', StorySchema);
StoryModel.update({}, { $rename: { votes: 'votesCount' } }, { multi: true, strict: false }, function(err, blocks) { });
Or do I not do this at all in the code? I have never dealt with database schema changes, so I'm not sure how / where to apply schema changes.
Make your changes in the Schema and the controller, as whatever name you use in your Schema field should also tally with the one in your Controller.
Eg.
const StorySchema = new Schema({
authorId: String,
title: String,
longUrl: String,
shortUrl: String,
comment: String,
category: String,
author: String,
date: { type: Date, default: Date.now, index: true },
votesCount: { type: Number, default: 1, index: true },
});
In your controller
let form = {
authorId:req.body.*****,
title:req.body.*****,
longUrl:req.body.*****,
shortUrl:req.body.*****,
comment:req.body.*****,
category:req.body.*****,
author:req.body.*****,
date:req.body.*****,
votesCount:req.body.*****
};
Note: the main point am trying to make here is that, the very name you used in the Schema should also the the same name you're gonna use for your controller.
I hope this is answers your question.
best use updateMany as
db.students.updateMany( {}, { $rename: { "nmae": "name" } } )
and change in your controller or directly replace previous field name to new field name where ever possible.
My Suggestion is better u first replace in controller or your project and if your project running in production update your new controller than u replace the field name using $rename

mongoose Foreign Key

I have a model called Portfolio that points to a user object using the user_id field. How can I model a many to one relationship with mongoose?
Portfolio
- user_id => is the id of a user object
Basically every portfolio object belongs to a user object.
I have the following code: Is this correct?
var PortfolioSchema = mongoose.Schema({
url: String,
createTime: { type: Date, default: Date.now },
updateTime: { type: Date, default: Date.now },
user:[
{type: Schema.Types.ObjectId, ref: 'User'}
]
});
Try this instead
var PortfolioSchema = mongoose.Schema({
url: String,
createTime: { type: Date, default: Date.now },
updateTime: { type: Date, default: Date.now },
user:{type: Schema.Types.ObjectId, ref: 'User'}
});

find all kinds but get one for every kind in mongodb

I create MessageScheme to save a message between two users, one document for one message. Now I want to find a list of people who have chated with specific person, what should I do?
I did this way, but it is not efficiency:
Message.find({$or: [{receiverId: specificId}, {senderId: specificId}]
}).sort('-created').limit(100).exec(function (err, results) {
res.jsonp(results) //the results will content all documents have specificId
})
This is the model in mongodb
var MessageSchema = new Schema({
created: {
type: Date,
default: Date.now
},
content: {
type: String,
default: '',
trim: true
},
senderId: {
type: String,
default: '',
},
receiverId:{
type: String,
default: '',
}
});