How can I get and populate the id ref to the order? I grab the id of the product and user. Then when I use my get method, I will get all the details of the products and users.
For example, my data will show all information
Product
a. title
b. price
c. productImage
User
a. username
b. studentId
I tried to use populate, but I think I'm doing it wrong.
export const getOrders = async (req,res) =>{
try {
const order = await Order.findOne({productId: '634e91d256326381d5716993'})
.populate()
.exec()
res.status(400).json(order)
} catch (error) {
res.status(404).json({message: error.message})
}
}
OrderSchema
const OrderSchema = mongoose.Schema({
productId: {type: mongoose.Schema.Types.ObjectId, ref: 'Product', required: true},
buyerId: {type: mongoose.Schema.Types.ObjectId, required: true, ref: 'User'},
sellerId: {type: mongoose.Schema.Types.ObjectId, required: true, ref: 'User'}
})
export default mongoose.model('Order', OrderSchema)
ProductSchema
const ProductSchema = mongoose.Schema({
user_id: {type: mongoose.Schema.Types.ObjectId, required: true, ref: 'User'},
title: {type: String},
description: {type: String},
categories: {type: Array},
price: {type: Number},
productImage: {type: String}
},
{ timestamps: { createdAt: true } }
)
export default mongoose.model('Product', ProductSchema)
UserSchema
const UserSchema = mongoose.Schema({
username: {type: String, unique: true, required: true},
password: {type: String, required: true},
email: {type: String, unique: true, required: true},
studentid: {type: String, unique: true, required: true},
isAdmin:{type: Boolean, default: false},
},
{ timestamps: { createdAt: true } }
)
export default mongoose.model('User', UserSchema)
You have to specify what you want to populate inside the .populate() method:
await Order.findOne({productId: '634e91d256326381d5716993'})
.populate([
{ path: 'productId', select: 'title price productImage' },
{ path: 'buyerId', select: 'username studentid' }
])
.exec()
Related
Hi every one please can someone help me to update user that receive image and updated it then render the user with the image to frontend.i get stuck I search by google but I didn't find what I search for,there's my code :
this is the userModel:
import mongoose from "mongoose";
const userSchema = new mongoose.Schema({
name: {type: String, required: true},
fname: {type: String, required: true},
phone: {type: String, required: true},
email: {type: String, required: true, unique: true},
password: {type: String, required: false},
image: {type: {name: String, img: {contentType: String, data: Buffer}}, required: false},
isAdmin: {type: Boolean, default: false, required: true},
}, {
timeStamps: true
});
const User = mongoose.model("User", userSchema);
export defau
userRouter.post("/upload/:id", async(req, res)=> {
upload.single("productImage")
const updatedUser = User.findByIdAndUpdate(req.params.id,{$set: {image: {name: req.files.productImage.name, img: {contentType: req.files.productImage.mimetype, data: fs.createReadStream(path.join(__dirname, '../../frontend/public/images'))}}}
})
res.send("ok");
console.log(updatedUser)
})
You have to add option {new: true}, so that the document returned has the last updated data, and also send the http response in the callback of the update operation
userRouter.post('/upload/:id', async (req, res) => {
upload.single('productImage');
const updatedUser = User.findByIdAndUpdate(
req.params.id,
{
$set: {
image: {
name: req.files.productImage.name,
img: {
contentType: req.files.productImage.mimetype,
data: fs.createReadStream(
path.join(__dirname, '../../../frontend/public/images')
),
},
},
},
},
{ new: true },
(err, doc) => {
if (err) return res.send(err);
res.send(doc);
}
);
});
My lines are empty.
My scheme:
// models/Tobacco.js
const mongoose = require('mongoose');
// FYI: important for populate work!!!
const tobaccoLineSchema = mongoose.Schema({
name: {type: String, required: true},
subTitle: {type: String, required: true},
count: {type: Number, required: true}
});
const Schema = mongoose.Schema;
const TobaccoSchema = new mongoose.Schema({
createdAt: {
type: Date,
default: Date.now
},
title: {
type: String,
required: true
},
subTitle: {
type: String,
required: false
},
bannerSrc: {
type: String,
required: false
},
socials: [],
lines: [
{
type: Schema.Types.ObjectId,
ref: 'tobaccoLine'
}
]
}
,{toObject:{virtuals:true}, toJSON:{virtuals:true}});
const TobaccoLine = mongoose.model('tobaccoLine', tobaccoLineSchema);
module.exports = mongoose.model('tobacco', TobaccoSchema);
Added populate line in API
router.get('/:id', (req, res) => {
Tobacco.findById(req.params.id).populate('lines')
.then(tobacco => res.json(tobacco))
.catch(err => res.status(404).json({ notobaccofound: 'No Tobacco found' }));
});
Database:
How I can't see issues. Client side fetches tobaccos but lines are empty.
Need to add back property into the child entity scheme.
const tobaccoLineSchema = mongoose.Schema({
name: {type: String, required: true},
subTitle: {type: String, required: true},
count: {type: Number, required: true},
_tobacco: { type: Schema.Types.ObjectId,
ref: 'tobacco' }
});
I have an array of posts and each post contains an author id. I want to loop through each post and find author from User model by using author id and then attach it to post. What is the best and efficient way to do it. I am currently doing it this way, but it decreases the performance. Thanks.
posts = await Promise.all(
posts.map(async post => {
post.author = await User.findById(post.author).lean();
return post;
})
);
// POST SCHEMA
const postSchema = new mongoose.Schema({
author: {
type: String,
required: true
},
body: {
type: String,
required: true
},
post_image: {
url: String,
public_id: String,
width: Number,
height: Number
},
date_created: {
type: Date,
default: Date.now()
}
});
// USER SCHEMA
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
register_date: {
type: Date,
required: true,
default: Date.now()
},
friends: {
type: Array,
default: []
}
});
// NEW POST SCHEMA
const postSchema = new mongoose.Schema({
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users',
required: true
},
body: {
type: String,
required: true
},
post_image: {
url: String,
public_id: String,
width: Number,
height: Number
},
date_created: {
type: Date,
default: Date.now()
}
});
// USER SCHEMA
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
register_date: {
type: Date,
required: true,
default: Date.now()
},
friends: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'users',
required: true
}],
});
You can use auto population of mongo object in mongoose. It won't cause performance issues as it uses id index. Similar to this doc: https://mongoosejs.com/docs/populate.html
Your query will look like this:
const post = await Post.find({ author: { $in: req.user.friends }})
.populate('author')
.exec();
console.log(post);
Or you can use aggregate according to this document: https://mongoosejs.com/docs/api/aggregate.html
Your query will then look like:
const query = [
{ $match: { author: { $in: req.user.friends } } },
{ $lookup: { from: "users", localField: "author", foreignField: "_id", as: "authorDetails" } },
{ $unwind: "authorDetails" },
]
const post = await Post.aggregate(query).exec();
console.log(post);
So the example right now is for the User table.. I have a UserWeapon document embedded that is an array of all the weapon's a user has and how many kills they have with the weapon. I want to write a query that when given the userId, weaponId, and new kills, it'll update the sub document accordingly.
So something like
const user = await User.findById(userId);
const userWeapon = await user.userWeapon.findById(weaponId);
userWeapon.kills = userWeapon.kills + newAmmountOfKills
user.save();
What would be the most efficient way to do this?
Schemas:
const UserWeaponSchema = new Schema({
weapon: { type: Schema.Types.ObjectId, ref: 'Weapon' },
user: { type: Schema.Types.ObjectId, ref: 'User' },
kills: {
type: Number,
required: true,
unique: false,
},
deaths: {
type: Number,
required: true,
unique: false
},
equippedSkin: {
type: Schema.Types.ObjectId, ref: 'WeaponSkin',
required: false,
},
ownedWeaponSkins: [{ type: Schema.Types.ObjectId, ref: 'WeaponSkin'}]
});
const UserSchema = new Schema({
username: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
weapons: [{
type: Schema.Types.ObjectId, ref: 'UserWeapon'
}],
});
You can use $inc operator and run update operation, something like:
UserWeaponSchema.update({ weapon: weaponId, user: userId }, { '$inc': { 'kills': newAmmountOfKills } })
Im trying MongoDB and as a matter of starting point im creating a schema for a chat application that may be simple to scale in the future, so im wondering if this looks correct from what i have been seeing in the docs. So far i have 3 collections User, Room, Message. Also i would need to perform some queries like getting all messages from a sepecific room, get all messages from a specific user, etc
Designed with mongoose:
var user = new mongoose.Schema({
username: { type: String, lowercase: true, unique: true },
email: { type: String, lowercase: true, unique: true },
password: String,
is_active: { type: Boolean, default: false },
});
var room = new mongoose.Schema({
name: { type: String, lowercase: true, unique: true },
topic: String,
users: [user],
messages: [message],
created_at: Date,
updated_at: { type: Date, default: Date.now },
});
var message = new mongoose.Schema({
room: room,
user: user,
message_line: String,
created_at: { type: Date, default: Date.now },
});
var User = mongoose.model('User', user);
var Room = mongoose.model('Room', room);
var Message = mongoose.model('Message', message);
//message model
'use strict';
import mongoose from 'mongoose';
var Schema = mongoose.Schema;
var ObjectId = Schema.Types.ObjectId;
var MessageSchema = new Schema({
send: {
type: ObjectId,
ref: 'User',
required: true
},
message: {
type: String,
required: true
},
date: {
type: Date
},
created_by: {
type: ObjectId,
ref: 'User',
required: true
},
thread: {
type: ObjectId,
ref: 'MsgThread',
required: true
},
is_deleted: [{
type: ObjectId,
ref: 'User'
}]
}, {
timestamps: {
createdAt: 'created_at',
updatedAt: 'last_updated_at'
}
});
export default mongoose.model('Message', MessageSchema);
//dont use rooms,,use thread like groupchat or personalChat
import mongoose from 'mongoose';
var Schema = mongoose.Schema;
var ObjectId = Schema.Types.ObjectId;
const s3 = require("../../utils/s3");
var MsgThreadSchema = new Schema({
users: [{
type: ObjectId,
ref: 'User'
}],
group_name: {
type: String
},
created_by: {
type: ObjectId,
ref: 'User'
},
community: {
type: ObjectId,
ref: 'Community'
},
image_url: {
type: String
}
}, {
timestamps: {
createdAt: 'created_at',
updatedAt: 'last_updated_at'
}
});
export default mongoose.model('MsgThread', MsgThreadSchema);