I'm trying to populate a mongoose query with an array of objectId field.
In another field with single objectId ref is working fine.
That's my "User" model:
const User = new Schema({
nome: {
type: String,
required: true
},
email: {
type:String,
required: true
}
})
mongoose.model('users',User)
That's my "Pedido" model:
const Schema = mongoose.Schema
const Pedido = new Schema({
id: {
type: String,
required: true
},
cliente: {
type: Schema.Types.ObjectId,
ref: 'clientes',
required: true
},
fotografos: {
type: [Schema.Types.ObjectId],
ref: 'users'
}
})
mongoose.model('pedidos',Pedido)
my router:
router.get('/pedidos',async(req,res)=>{
var query = await Pedido.find().populate('fotografos').populate('cliente').lean().exec()
console.log(query)
res.render("admin/pedidos",{pedidos: query})
})
That's the result in the console.log:
[
{
_id: 5e8e3bd16c57021f682b8e81,
fotografos: [],
cliente: {
_id: 5e8ccceea8a28146d86f4cac,
nome: 'Neymar',
email: 'neymar#ney.com',
__v: 0
},
__v: 0
}
]
fotografos field (array) are returning empty.
clientes field returns populated.
Can anybody help me with this?
You can use this code...
fotografos:[{
type: [Schema.Types.ObjectId],
ref: 'users'
}]
**Then do Populate**
Related
I want to ref a slot by objectid which is inside an array of object in different schema,
Here is my DoctorSlots schema:
const DoctorSlots = new mongoose.Schema({
doctor: { type: mongoose.Schema.Types.ObjectId, ref: 'Doctors' ,required: true ,trim: true},
slots: [{
startTime: {type: Date, },
endTime: { type: Date },
status: {type: String, default: "active"
} //this is the object that i want to ref
}]
},{timestamps: true})
const slotSchema = mongoose.model('doctorslots',DoctorSlots)
this is appointment schema
const AppointmentSchema = new mongoose.Schema({
userDetails: {type: mongoose.Schema.Types.ObjectId, ref: 'User', required:true },
doctorDetails: { type: mongoose.Schema.Types.ObjectId,ref: 'Doctors' ,required: true },
appointTime: {
time: {
type: mongoose.Schema.Types.ObjectId, ref: ''
} //here i want to ref that slot objcet id inside that array
}
}, {timestamps: true})
const appointmentSchema = mongoose.model('appointments', AppointmentSchema)
I want to ref an object in time: field of appointment schema which will refer an object from slots(array of obj) of doctorslots schema. what should be inside " ref:'' "?
How can I populate category in courses model?
I have courses, courses will have category from categories->subcategories model.
I don't know how to populate from nested objects.
Reference model is category, I have to populate from array subcategories!
**courses:**
const CourseSchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
name: {
type: String
},
description: {
type: String
},
category: {
type: mongoose.Schema.Types.ObjectId,
ref: 'category'
}
});
**category:**
const mongoose = require("mongoose");
const CategorySchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
name: {
type: String,
required: true
},
subcategories: [{
name: {
type: String
}
}]
});
const Category = mongoose.model('category', CategorySchema);
module.exports = Category;
use seprate collection for subCetagory like:
**courses**
const CourseSchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
name: {
type: String
},
description: {
type: String
},
category: {
type: mongoose.Schema.Types.ObjectId,
ref: 'SubCategory'
}
});
**SubCategory:**
const mongoose = require("mongoose");
const SubCategorySchema = new mongoose.Schema({
name: {
type: String,
required: true
},
categorie: {
type: String,
ref: "category"
}
});
const SubCategory = mongoose.model('category', SubCategorySchema);
module.exports = SubCategory;
**Category**
const mongoose = require("mongoose");
const CategorySchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
name: {
type: String,
required: true
},
subcategories: [
{
type: Schema.types.objectId,
ref: "SubCategory"
}
]
});
then just add subcetagory id to course when insert new course or update a course and when you want to get course along with subcetagory and category use populate query of mongoose
I'm trying to have each record attached to a user who created it,
and every user have their records attached.
Here are my schemas:
1.The Records schema:
const mongoose = require('mongoose')
const RecordsSchema = new mongoose.Schema(
{
Title: { type: String, required: true },
postedby:[{
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
}],
Author: { type: String, required: true},
ISBN: { type: String, required: true },
Review: { type: String },
SelectedFile: { type: String },
Likes: { type: Number, default:0},
Date: { type: Date, default: Date.now()}
});
module.exports = Records = mongoose.model('record', RecordsSchema', 'record');`
Here is the The user Schema:
const mongoose = require('mongoose')
const userSchema = new mongoose.Schema(
{
username: { type: String},
email: { type: String, required: true ,unique:true},
records:[{
type: [mongoose.Schema.Types.ObjectId],
ref: 'record' }],
password: { type: String, required: true},
Date: { type: Date, default: Date.now(), immutable: true }
});
module.exports = User = mongoose.model('user', userSchema,'user');
The express route for getting a record:
router.get('/postedby/', (req, res) => {
Records.find(req.params.id)
.populate('postedby')
.exec()
.then(post =>{
if (!post) {
return res.status(400).json({ msg: 'Add Posts' });
}
else return res.json(post);
}).catch (err => console.error(err))
});
Result of the route:
{
"postedby": [],
"Likes": 0,
"_id": "5fed8c12a4fb2c1e98ef09f6",
"Title": "New Age",
"Author": "Situma Prisco",
"ISBN": "23422",
"SelectedFile": "",
"Review": "",
"Date": "2020-12-31T08:30:10.321Z",
"__v": 0
},
I'm getting a blank Array on the populated user field(posteddby) .
Please help, What am I doing wrong? And yes, i do have a User Logged in
You are too close.
In your schema definition, postedby field itself is an array. Hence you can simply define it like :
postedby:[{
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
}]
Make sure that the ObjectID is stored properly in the postedby array.
Also, you are trying to find a single record based on the ID, hence you can use findById(req.params.id) or findOne({_id:req.params.id}) which would return a single document.
The field (viewed_posts) i want to populate in User Schema:
viewed_posts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Viewed"
}
]
Viewed Schema :
var viewedSchema = new mongoose.Schema({
hitsByUser: {type: Number, default: 0},
viewsByUser: {type: Number, default: 0},
post: {
type: mongoose.Schema.Types.ObjectId,
ref: "Post"
}
});
Post Schema :
var mongoose = require('mongoose');
var passportLocalMongoose = require("passport-local-mongoose");
var uniqueValidator = require('mongoose-unique-validator');
var marked = require('marked');
var slugify = require('slugify');
// this is done for sanitizing html so that user cannot write a script in the input
const createDomPurify = require('dompurify')
const {JSDOM} = require('jsdom')
const dompurify = createDomPurify(new JSDOM().window)
var postSchema = new mongoose.Schema({
postNumber: Number,
title: String,
content: String,
subject: String, // currently we have 4 subjects so one out of 4 subjects will be stored here
likes: {type:Number,default:0},
// likes: {
// id:{
// type: mongoose.Schema.Types.ObjectId,
// ref: "User"
// }
// },
views: {type:Number,default:0},
actualViews: {type:Number,default:0},
shares: Number,
isReviewedByAdmin: {type: Boolean, default: false},
isReviewedByAuditor: {type: Boolean, default: false},
author: {
id:{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: {
type: String
}
},
publish_date: {
type: String,
default: Date.now
},
publishDay: String,
slug: {
type: String,
required: true,
},
sanitizedHtml: {
type: String,
required: true
},
imagename: String //2002-12-09
});
I wish to see whole structure printed , but i can only populate viewed_posts, how can i populate "post"
which is inside viewed Schema and see here:
User.findById(req.user._id).populate("viewed_posts").exec((err,ans)=>{
if(err) console.log(err)
else{
console.log("this is the answer ",ans)
}})
The output i get:
},
{
hitsByUser: 0,
viewsByUser: 0,
_id: 5f9e85aeec37700f54a4d029,
post: 5f9a93d38d7cf8544ce9cc21,
__v: 0
},
{
hitsByUser: 0,
viewsByUser: 0,
_id: 5f9e85d61841000478c85f8a,
post: 5f82773f1998150024d4c8fc,
__v: 0
},
But i expect this post to be expanded too, instead of just showing id , How can i achieve it. Any Help Would be appreciated.
Mongoose supports nested populating (see in the docs: https://mongoosejs.com/docs/populate.html#deep-populate).
Note that you have to specify your model name of post schema where I´ve put the "post-model-name" placeholder.
So you could try something like this:
User.findById(req.user._id)
.populate({
path: 'viewed_posts',
populate: {
path: 'post',
model: 'post-model-name'
}
})
.exec();
Hello im trying to join these collections i want to get all users which has "active" attribute equal to false. I couldn't figure out how to acquire this query. There are my schemas:
User Schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
type: {
type: String,
required: true
},
active:{
type:Boolean
}
});
module.exports = mongoose.model('users', UserSchema);
Company Schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CompanySchema = new Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
companies: [{
name: {
type:String
},
country:{
type:String
}
}
]
});
module.exports = Company = mongoose.model('company', CompanySchema);
Note: Not all users have companies only the type "client" and i want to get both, "client" and "employe"
You may want to refactor your Schema to better accommodate the type of data you have available.
For example:
User Schema:
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
type: {
type: String,
required: true
},
active:{
type:Boolean
},
companies: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'company'
}]
});
And Company Schema:
const CompanySchema = new Schema({
name: {
type:String
},
country:{
type:String
}
});
Then to get a list of all users who are active, and automatically populate any company data for those users (Assuming your user model is called UserModel)
UserModel.find({ active: false }).populate('companies').exec();
If you are unable to edit your data structure for any reason, then you could perform a query similar to:
CompanyModel.aggregate([
{ $lookup: { from: 'users', localField: 'userId', foreignField: '_id', as: 'user' } },
{ $match: { '$user.active': false } }
]).exec()
This will perform an aggregate lookup on the UserId field and then only match on ones where the active property is set to false.