Mongoose select with populate not working - node.js

I am making a query in mogoose and if i add any parameter on a query select, the populate parameter goes missing for example i have the following schemas:
Department:
var mongoose = require('mongoose');
var schema = mongoose.Schema({
name: {type:String,required: true,index: {unique: true}} ,
text: String
})
module.exports=mongoose.model('Department',schema);
Employee:
var mongoose = require('mongoose');
var ObjectId=mongoose.Schema.ObjectId;
var schema = mongoose.Schema({
name: {type:String,required: true} ,
lastName: {type:String} ,
birthday:Date,
email:{type:String,required: true,index: {unique: true}},
_department:{type:ObjectId,ref:'Department'},
isUser:Boolean
},{ strict:false});
module.exports=mongoose.model('Employee',schema);
if i make:
var query=mongoose.model('Employee').find();
query.select('email').populate('_department','name');
query.exec(function(err,data){
console.log(data);
});
I get the following ouput
[ { email: 'email#email.com.br', _id: 532e570864803bf505e51c81 } ]
I would expect this:
[ { _department: { _id: 532c77c3485925d806436981, name: 'bar' },
email: 'email#email.com.br',
_id: 532e570864803bf505e51c81,
__v: 0 } ]
If i make the following:
var query=mongoose.model('Employee').find();
query.populate('_department','name');
query.exec(function(err,data){
console.log(data);
});
I get this output
[ { _department: { _id: 532c77c3485925d806436981, name: 'bar' },
name: 'mimimi',
email: 'email#email.com.br',
_id: 532e570864803bf505e51c81,
__v: 0 } ]
What makes me wonder that the select is breaking the populate.
My mongoose version is 3.8.8

Surely you just specify the fields you want. Currently you only have "email" so that is all you get:
var query=mongoose.model('Employee').find();
query.select('email _department').populate('_department','name');
query.exec(function(err,data){
console.log(data);
});

Try my code:
const Employee= require('../models/employee');
Employee.find({}, 'email _department')
.populate('_department', ['name'])
.exec(function(err, list_employee) {
if (err) { return next(err); }
//Successful
console.log(list_employee);
});
Will work for you!

Work for me this in mongoose and here company_name field is getting populate via reference
ModelName.find().populate('parent_id', 'company_name')
.select('username mobile firstname lastname company_name');

Related

Return list of saved items using populate() in Mongoose

I am trying to create a page displaying saved items per user, so far my view is showing the JSON string, I want to render the original document (image, title, date,..)
Trying to understand populate() better.
Thanks
In DB
{
"_id":{"$oid":"6089d131efbe7e3e0c5c51f3"},
"joinDate":{"$date":"2021-04-28T21:17:06.928Z"},
"name":"...",
"email":"...",
"password":"...",
"createdAt":{"$date":"2021-04-28T21:18:41.832Z"},
"updatedAt":{"$date":"2021-04-28T21:18:41.832Z"},
"__v":0,
"avatar":"18756.png",
"savedArticles":[
"5eb91189c2de0f24fc1517db", // >> ObjectId of original
"585ad7294a91aa0de83d8ac4"
]}
My function:
router.get('/savedItems/:id/', checkAuthenticated, (req, res) => {
const id = req.params.id;
mongoose.model('Users').find({
_id: id
})
.populate('savedArticles', 'title')
.exec(function(err, results) {
if (err) {
console.log(err)
return;
}
res.render('savedItems.ejs', { savedArticles: results, user: req.user })
console.log( JSON.stringify(results))
});
})
Models:
var Schema = mongoose.Schema;
var userSchema = new Schema({
// ...
savedArticles:[{type: Schema.Types.ObjectId, ref: 'Article' }]
},{ autoCreate: true})
var Schema = mongoose.Schema;
var articleSchema = new Schema({
title: { type: String, required: true },
//...
})
const Users = mongoose.model('Users', userSchema)
const Article = mongoose.model('Article', articleSchema)
In view:
<% for(i=0; i < savedArticles.length; i++) {%>
<a href='#'><%= savedArticles[i].savedArticles %></a>
<% } %>
Output:
{ _id: 5eb91189c2de0f24fc1517db, title: 'Gatsby' },
{ _id: 585ad7294a91aa0de83d8ac4, title: 'Blade runner' }
Output Update with objects
{
_id: ...,
name: '',
email: '',
password: '....',
savedArticles: [
{
_id: ...,
title: '...',
director: '...',
year: '...'
},
{
_id: ...,
title: '...',
director: '...',
year: '...'
}
],
}
When you do populate, then mongoose will based on the _ids that are stored in savedArticles array go and fetch from the Articles collection documents with those _ids and it will change _ids in savedArticles array with actual documents. So, when your frontend got the result, savedArticles array will be array of objects (documents from Articles collection) and not array of _ids.
Now you can iterate over that array and access specific field of each article, like: savedArticles[0].title.

Inserting an object into a list on a mongoDB collection

I have a collection created with the below schema
const userSchema = new mongoose.Schema({
Name: String,
email: String,
music: Array
});
var User = new mongoose.model("User", userSchema);
However, i am having issue inserting the object below into the music array
var newMusic = {
artist: "Rihanna",
title: "Believe It"
};
Below is the code i am running to insert the above into the music array
User.update({
_id: req.user._id
}, {
$push: {
music: newMusic
}
});
No error message, just not updating the document.
I finally figured it out. The below code works
User.update({
_id: req.user._id
}, {
$push: {
music: newMusic
}
}).then(data => {
console.log(data);
});

mongoose query with $in property

var mongoose = require('mongoose');
var FriendSchema = new mongoose.Schema({
requester: {
type: String,
required: true,
},
recipient: {
type: String,
required: true,
},
});
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var Friend = mongoose.model('Friend', FriendSchema);
module.exports = Friend;
I am trying to query it by using
Friend.find({"requester": { $in: [some id value]}}, function(err, fee){
console.log(fee.recipient);
});
and having it return the recipient id value..
Any suggestions would really be helpful, thank you.
you can use projection of mongo.db
the structure is like below ,
find(condition , requirefield , callback);
below is the example in which the fee will contain only the recipient
Friend.find({"requester": { $in: [some id value]}}, { _id : 0 , requester : 0 } ,function(err, fee){
console.log(fee.recipient);
});
you can refer https://docs.mongodb.com/manual/reference/method/db.collection.find/#projections for more reference.

Populate in Mongoose not working

I am trying to perform associations by referencing method. There are 2 models:
1. User
2. Product
I have established one-to-one relationship of 1 user can have multiple products. User creation is successful
Product creation is successful
Code Inputs
var mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/product_demo_x9");
Product Schema
var productSchema = new mongoose.Schema({
category : String,
Brand: String
});
var Product = mongoose.model("product", productSchema);
User Schema
var userSchema = new mongoose.Schema({
email: String,
name: String,
products: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Product"
}
]
});`
var User = mongoose.model("user", userSchema);
User Creation
User.create({
email: "madhur#google.com",
name: "Maddy"
},function(err,newUser){
if(err){
console.log(err);
}
else {
console.log(newUser);
}
});
Product Creation
Product.create({
category: "Smartwatches",
Brand: "Samsung and Google"
},
function(err,product){
console.log(product);
User.findOne({name : "Maddy"},function(err,foundUser){
if(err) {
console.log(err);
}
else {
foundUser.products.push(product);
foundUser.save(function(err,updatedUser){
if(err){
console.log(err);
}
else {
console.log(updatedUser);
}
});
}
});
});
Display of associated Data on the console
User.find({email: "madhur#google.com"}).
populate("products").
exec(function(err,user){
if(err){
console.log(err);
}
else {
console.log(user);
}
});
Code Outputs
User Creation (Success)
[{
products: [],
_id: 5a47acb0317d4e3c2081b8ce,
email: 'madhur#google.com',
name: 'Maddy',
__v: 0
}]
Product Creation and associating (Success)
{
_id: 5a47acd53c771123b4018ff1,
category: 'Smartwatches_2',
Brand: 'Samsung and Google',
__v: 0
}
{
products: [ 5a47acd53c771123b4018ff1 ],
_id: 5a47acb0317d4e3c2081b8ce,
email: 'madhur#google.com',
name: 'Maddy',
__v: 1
}
Display of embedded data using populate - Failure!!
{ MissingSchemaError: Schema hasn't been registered for model "products".
Use mongoose.model(name, schema)
at new MissingSchemaError
Can anyone please explain me how to do it correctly?
Thanks in Advance
Model Name is Case-sensitive
'Product' is not equal to 'product'
and when u create a model as 'product' (singular) it converts it into plural, i.e. 'products', this is default mongoose behavior, can be overridden.
so change the following:
var userSchema = new mongoose.Schema({
email: String,
name: String,
products: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "products" //<---- changed 'Product' to 'products'
}
]
});`
var User = mongoose.model("user", userSchema);
Try this
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/product_demo_x9');
var productSchema = new mongoose.Schema({
category: String,
Brand: String
});
var Product = mongoose.model('Product', productSchema);
var userSchema = new mongoose.Schema({
email: String,
name: String,
products: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Product'
}
]
});
var User = mongoose.model('User', userSchema);
User.create({
email: 'madhur#google.com',
name: 'Maddy'
}, function(err, newUser) {
if (err) {
console.log(err);
} else {
console.log(newUser);
}
});
Product.create({
category: 'Smartwatches',
Brand: 'Samsung and Google'
},
function(err, product) {
console.log(product);
User.findOne({name: 'Maddy'}, function(err, foundUser) {
if (err) {
console.log(err);
} else {
foundUser.products.push(product);
foundUser.save(function(err, updatedUser) {
if (err) {
console.log(err);
} else {
console.log(updatedUser);
}
});
}
});
});
User.find({email: 'madhur#google.com'})
.populate('products')
.exec(function(err, user) {
if (err) {
console.log(err);
} else {
console.log(user);
}
});
Solved
Did the following
Downgraded my Mongoose version from 5.00x to 4.10.8 using the following command npm remove mongoose then npm install mongoose#4.10.8 --save
Made the following change in app.js file
var userSchema = new mongoose.Schema({
email: String,
name: String,
products: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "product" //<---- changed 'Product' to 'product'
}
]
});`
var User = mongoose.model("user", userSchema);
Thanks to the Stack community for giving a try!

retrieve date failed in mongoose

I defined my mongoose schema like this
var personSchema = new Schema({
id: 1
data: [{
dob: Date,
gender: String,
}]
});
Then I do
Person.find({"data.dob": new Date('1-2-2016')}, function(err,result) {
res.json(result)
});
I got empty array, any clue why? I also tried
Person.find({"data.dob": "1-2-2016"}, function(err,result) {
res.json(result)
});

Resources