My code was working well when i was using findById. I want to make slug so i used mongoose-slug-generator. and i used find to get the data from the Database.
The problem is i get the data back while using find method but i cannot access it as a JavaScript Object.
data returned by find method
{
category: [
{
subCategory: [Array],
product: [Array],
_id: 60e14e0994e27f3a2c93a26a,
category: 'Electronics',
image: 'images\\2021-07-04T05-58-33.034Z-download.jpg',
createdAt: 2021-07-04T05:58:33.108Z,
updatedAt: 2021-08-31T13:35:12.140Z,
__v: 0
}
],
subCategory: [
{
category: [Array],
product: [Array],
_id: 60e14e2294e27f3a2c93a26c,
subCategory: 'Laptop',
createdAt: 2021-07-04T05:58:58.554Z,
updatedAt: 2021-08-31T13:35:12.142Z,
__v: 0
}
],
brand: [
{
product: [Array],
_id: 60e14e6294e27f3a2c93a271,
brand: 'sound',
image: 'images\\2021-07-04T06-00-02.355Z-brand_4.png',
createdAt: 2021-07-04T06:00:02.370Z,
updatedAt: 2021-08-31T13:35:12.145Z,
__v: 0
}
],
rating: [],
sellCount: '0',
color: [ 'blue' ],
size: [ 'LG' ],
image: [ 'images\\2021-08-31T13-35-12.116Z-hac-hdbw1231ra-z-a.png' ],
_id: 612e3010abd51525286ea7e9,
title: 'CCTV DAUHA HD 2.0 MP camera for security test2',
description: 'THis is discription',
price: 200,
discount: 2,
quantity: 200,
feature: false,
active: true,
stock: true,
createdAt: 2021-08-31T13:35:12.130Z,
updatedAt: 2021-08-31T13:35:12.130Z,
slug: 'cctv-dauha-hd-2-0-mp-camera-for-security-test2-rTfwYsVts',
__v: 0
}
controller
exports.getSingleProduct = (req, res, next) => {
let slug = req.params.slug
Product.find({slug: slug})
.populate("category")
.populate("subCategory")
.populate("brand")
.populate({
path: 'rating',
populate: {
path: 'user',
model: 'User'
}
})
.then((product) => {
console.log("controller" + product.title)
let brandId =product.brand[0].id
Product.find({ brand: brandId })
.then((brand) => {
res.render("user/single-product", {
product,
user: sessionUser,
featured: req.featured,
categories: req.categories,
related: req.related,
brand,
bestSeller: req.bestSeller,
banner: req.banner,
mostRated: req.mostRated,
storelists: req.storelists,
});
})
.catch((err) => {
console.log(err);
})
})
.catch((err) => {
console.log(err)
})
}
code use to work but not working now
console.log("controller" + product.title)
used to work when there was finById method used.
what is the problem? thank you
I'm Populating array of objects i don't know how i didn't get the result ?
Here my Schema for Todo model Each todo can have multiple collaborators
collaborators: [{
collaborator: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'Users'
}
}]
the code doing the populate
const task = await Todo.find().populate('collaborators.collaborator').exec()
and i expected this query will give the todo info and all collobarotor info as well but only it give as a todo info only
Result i get
[
{
_id: 5eb672eb197e5d1afca21a23,
title: 'testing colla',
todo_description: 'paptefhfbjebjfbhjebfa.m',
priority: 'Low',
duedate: 2020-05-09T09:07:30.000Z,
image: [ [Object] ],
status: 'In Progress',
userid: 5e900762314fd13148cd3393,
assignee: 'nikil',
collaborators: [ [Object], [Object] ],
__v: 0
}
]
hello i went to populate all author with Course.
const courses = await Course.find().populate('author','name -_id');
console.log(courses);
const Author = mongoose.model('Author',mongoose.Schema({
name:{
type:String,
required:true
},
bio:String,
website:String
}));
const Course = mongoose.model('Course',mongoose.Schema({
name:String,
author:[{
type: mongoose.Schema.Types.ObjectId,
ref:'Author'
}]
}));
this is what i get:
[ { author: [ [Object], [Object] ],
_id: 5cdc596bfd5a1e33e4833b2b,
name: 'nodejs course',
__v: 1 } ]
but i went to populate author name inside the author array
like this [{author:[{name:'jhon'},{name:'jhon2'}],
[ { author: [ [Object], [Object] ],
_id: 5cdc596bfd5a1e33e4833b2b,
name: 'nodejs course',
__v: 1 } ]
I believe this should work for you:
const courses = await Course
.find({})
.populate('author')
.exec();
console.log(courses);
i'm trying to do a $lookup in a collection and add some data to my documents. The problem is that when i try matching my $lookup pipeline by _id it returns an empty array. Here is my code:
Schedule.aggregate([{ // My Schedule schema
$match: {
store: req.query.store,
"customer.id": req.query.user
}
},
{
$skip: +req.query.skip
}, {
$limit: +req.query.limit
},
{
$lookup: {
from: Employee.collection.name, // "employee" schema,
let: {
id: "$employee.id" // employee _id from the "schedule" collection match above
},
pipeline: [{
$match: {
$expr: {
"_id": "$$id" // here i try to match by _id
}
}
},
{
$project: { // the only fields i need
"_id": 1,
"avatar": 1,
"name": 1
}
}
],
as: "employees" // employees is returned as []
}
}
]).exec((err, resolve) => {
if (err) console.log('error', err);
res.json(resolve);
});
If it helps here's both my collections used in this aggregation:
Schedule schema:
const ScheduleSchema = new Schema({
store: {
type: String,
required: true
},
customer: {
id: {
type: String
},
name: {
type: String
},
avatar: String,
phone: {
type: String
},
email: { type: String },
doc: {
type: String
},
},
employee: {
id: {
type: mongoose.Schema.Types.ObjectId,
required: true
},
name: {
type: String,
required: true
},
avatar: String,
},
service: {
id: {
type: String
},
name: {
type: String,
required: true
},
filters: [String]
},
info: {
channel: {
type: String,
required: true,
default: 'app'
},
id: mongoose.Schema.Types.ObjectId,
name: String
},
scheduleDate: {
type: String,
required: true
},
scheduleStart: {
type: String,
required: true
},
scheduleEnd: {
type: String,
required: true
},
value: {
type: Number
},
comissionType: {
type: String,
default: '$'
},
comissionValue: {
type: Number,
default: 0
},
status: {
type: Number,
required: true
},
observation: String,
paymentMethod: {
type: Number,
default: 0
},
paymentValue: String,
paymentChange: String,
color: String
}, {
timestamps: {
createdAt: 'created',
updatedAt: 'updated'
}
});
Employee Schema:
const EmployeeSchema = new Schema({
name: {
type: String,
required: true
},
a_to_z: String, // nome normalizado, só minusculas e sem espaços
description: String,
email: {
type: String,
required: true
},
avatar: String,
phone: {
type: String
},
storeOwner: {
type: Boolean,
required: true
},
permissions: [
{
route: String,
hasPermission: Boolean
}
],
scheduleAutomatic: {
type: Boolean,
required: true,
default: false
},
password: {
passwordHash: String,
salt: String
},
active: {
type: Boolean,
default: true
},
storeKey: {
type: String,
required: true
},
notification_token: String,
notification_tokens: {
type: [String],
default: []
},
workingHours: [{
weekDay: {
type: Number,
},
doesWork: {
type: Boolean,
},
startHour: String,
endHour: String,
lunchStart: String,
lunchEnd: String
}],
config: {
available_days: {
type: Number,
default: 365
},
in_advance_schedule: {
type: Number,
default: 0
},
in_advance_interval: {
type: String,
default: 'minute'
}
}
}, {
timestamps: {
createdAt: 'created',
updatedAt: 'updated'
}
});
EDIT
The result i'm trying to achieve is this:
The employees property is the one i'm trying to use $lookup to get, it'll have the same data as the employee property, in the end it'll be and array of objects with just one object inside.
Some sample docs:
Schedule:
color: "lavander",
created: "2018-07-31T18:50:53.423Z",
customer: {id: "5b60a67206e8a65f48a15f13", name: "Gabriel Barreto", phone: "11995274098", cpf: "40735255814"},
employee: {id: "5b2952c68424872fccece7f5", name: "Gabriel Barreto", avatar: null},
observation: "teste",
scheduleDate: "2018-08-01",
scheduleEnd: "2018-08-01 08:30",
scheduleStart: "2018-08-01 08:00",
service: {filters: Array(3), id: "5b606e8cc59e82354cc931e2", name: "Corte Masc"},
status: 1,
store: "5b16cceb56a44e2f6cd0324b",
updated: "2018-11-27T13:27:40.310Z",
value: 25,
__v: 0,
_id: "5b60af8de558661acc5d70b9"
Employee:
a_to_z: "gabrielbarreto",
active: true,
avatar: "gabriel_barreto_h7qvcn.jpg",
config: {available_days: 180, in_advance_schedule: 10, in_advance_interval: "hour"},
created: "2018-06-19T19:00:22.315Z",
currency: "BRL",
description: "Novo perfil",
email: "gabriel.barreto#wabiz.com.br",
lang: "pt-BR",
name: "Gabriel Barreto",
notification_token: "2d768670-6011-4873-846d-39580b0d82d0",
notification_tokens: ["53049a82-53dc-4bc3-9646-7a4bee1f367b"],
password: null,
permissions: (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}],
phone: "11995274098",
scheduleAutomatic: false,
storeKey: "5b16cceb56a44e2f6cd0324b",
storeOwner: true,
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImdhYnJpZWwuYmFycmV0b0B3YWJpei5jb20uYnIiLCJpYXQiOjE1NTA2NzEwNDQsImV4cCI6MTU1MzI2MzA0NH0.0Odizd8pS4WPGSqm_2_XrTw1YE8NMOOXnHIrG-WVxGo",
updated: "2019-02-20T13:34:20.619Z",
workingHours: (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}],
__v: 0,
_id: "5b2952c68424872fccece7f5"
Thanks for your time
I was in trouble too while using $lookup with mongoose to trying to match _id as my collection store the reference as a String and not an ObjectId
Model A: {_id: ObjectId("xxx"), b_id: "eeeee"}
Model B: {_id: ObjectId("eeeee")}
MyCollectionA.aggregate([
{
$lookup: {
from: "collectionb",
let: {id: "$b_id"},
pipeline: [{$match: {$expr: {$eq: ["$_id", "$$id"]}}}],
as: b
}
])
In this example b is never filled as $$id is not considered as an ObjectId
Just add a project to transform $$id in an objectId and its working
MyCollectionA.aggregate([
{
$lookup: {
from: "collectionb",
let: {id: "$b_id"},
pipeline: [
{$project: {_id: 1, bid: {"$toObjectId": "$$id"}}},
{$match: {$expr: {$eq: ["$_id", "$bid"]}}}
],
as: b
}
])
Or with foreignField, localField:
MyCollectionA.aggregate([
{
$project:{
_id: 1,
b_id: {"$toObjectId": "$b_id"}
}
},
{
$lookup: {
from: "collectionb",
localField: "b_id",
foreignField: "_id",
as: b
}
])
This worked for me:
MyCollectionA.aggregate([
{
$lookup: {
from: "collectionb",
let: {id: "$b_id"},
pipeline: [
{$match: {$expr: {$eq: ["$_id", {"$toObjectId": "$$id"}]}}}
],
as: b
}
])
Is there a way to exclude lessons.lesson_id that are equal to null? I have the following from previous answers, but it's still giving lessons.lesson_id that are null
module.exports.getClasses = function(id, callback){
Class.findById(id)
.populate(
{path: 'lessons.lesson_id',
model: 'Lesson', $ne: null}
).exec(callback)
}
var classSchema = new Schema({
title: { type: String, required: true },
lessons: [{
_id: false,
lesson_id: {type: mongoose.Schema.Types.ObjectId, ref: 'Lesson'}
}],
});
I'm trying to prevent the lesson_id with null from showing up
{ _id: 58090,
title: 'vcvc',
__v: 0,
lessons: [ { lesson_id: null }, { lesson_id: [Object] } ] }
So your ClassSchema is a touch off, I think you may find this will work better based on your requirements:
var classSchema = new Schema({
title: { type: String, required: true },
lessons: [{type: mongoose.Schema.Types.ObjectId, ref: 'Lesson'}],
});