How to populate nested array in Mongoose - node.js

I got stuck at populating my array... this is what i get from my Terminal.find() function:
{ _id: 5a7300046f18140d5081be83,
type: 5a71a22b0d4a2d0ec3b91edc,
serial: '213',
macAddress: 'E1:12:BE:82:12',
barcode: '1243w464563',
dateArrival: 2018-02-01T11:54:15.870Z,
firmware: 5a71a2030d4a2d0ec3b91edb,
installedAt: 5a61e547922c6d28e324d775,
installedAtBranch: 5a7054713fe20c0c5a94fb11,
__v: 0,
deleted: false,
activated: true }
So i want to get the correct information, when a user searches for the terminal. This is why i have to use populate(). Difficult for me now is to populate things deeper inside the array. So the first Object type has a readMethod, a layout and interfaces - i have to populate those three, but i don't know how. This is aggravated by the fact that interfaces is an Object inside my Database. So my type looks like this:
I think if someone can show me how to populate type with all of its interfaces i can achive the rest on my own.
Thanks in advance!
I found the answer on my own by searching deeper inside google:
Terminal.findOne({'barcode': barcode})
.populate({
path: 'type',
populate: [{
path: 'user',
model: 'User'
},
{
path: 'method',
model: 'Method',
},
{
path: 'layout',
model: 'Layout'
},
{
path: 'interfaces',
model: 'Interface'
}]
})
.populate('firmware')
.populate('customerId')
.populate('branchId')
.exec( function (err, terminal) {
if (err) {
res.status(500).send(err);
}
res.json({ terminal });
});

As you are using mongoose then I think your model should look like following or it must be like following
Terminal Type Schema
var terminalTypeSchema = new Schema({
articlenumber: { type: Number, default: something },
readMethod: Schema.ObjectId,
layout: Schema.ObjectId,
interfaces: [{ type: Schema.ObjectId, ref: 'User' }]
});
mongoose.model('TerminalType', terminalTypeSchema);
Interface Schema
var interfaceSchema = new Schema({
// some vars
});
mongoose.model('Interface', interfaceSchema);
Now run following query
TerminalType.findOne({ _id: terminalTypeId})
.populate('interfaces') // <==
.exec(function(err, terminalTypes){
// You can achieve the rest on your own.
});

Related

Using DELETE Rest api to remove array object from Mongodb

I am using Node.js, express, mongodb, and mongoose. I have two files: favorite and favorite-route.
"favorites" in the schema has multiple objects in it array. Given the mongodb assigned _id, I would like to create a delete method to gremove the specified object in the array.
Here is my schema in favorite:
userID:{
//type: String,
type: mongoose.Schema.Types.ObjectId,
ref: "user",
required: true,
unique: true
},
favorites:[{
publication: {
type:mongoose.Schema.Types.ObjectId,
ref: "Pet"
},
id: {
type: String,
required: true
},
comment: {
type: String,
required: true
}
}]
})
favoritesSchema.statics.deleteFavorite = async (favID)=>{
return await Favorite.findOneAndUpdate({favID})
}
This is my delete method in favorite-route file:
router.delete('/:favID', async (req,res)=>{
let doc = await Favorite.deleteFavorite(req.params.favID)
if(doc){
doc.splice(req.params.favID);
res.send(doc)
return;
}
res.status(404).send({error: "no se encontró esa publicación"})
})
And lastly, here is my http:
DELETE {{host}}/api/favorites/626eddd14762eb4ae4c77f9e
When i test this, it gives me the error:
TypeError: doc.splice is not a function
I'd appreciate any tips and insight. I have spent a while searching for answers but most suggested using $pull, which I am unsure how to implement in the delete method.
Thank you :)
you should do.
Favorite.updateOne(
{ userID: user._id }, // this is the query to find the desired favourite list
{ $pull: { favorites: { id : req.params.favID }} }, // this removes
);

Check against multiple fields when using Mongoose Virtual schema?

I am a little stuck with trying to figure out the best way to populate a virtual schema in my db. In this instance, I want to check against multiple fields but I do not know any way to do this or alternative ways.
I had hoped I could just use some string arrays in the 'localField' & 'foreignField' keys of the virtual schema but this was not the case.
The user has a 'Series' _id saved, and the virtual schema 'leagues' gets all leagues that the user is entered into too, the catch is a league belongs to different Series. I want to only retrieve the leagues that the user is entered into & that match up with the user's series _id also...
As you can see currently this virtual schema just returns all the leagues the user is entered into regardless of the series. :(
Any ideas? I have been very confused about how to achieve this.
const schema: mongoose.Schema = new mongoose.Schema({
_id: {
type: mongoose.Schema.Types.ObjectId,
auto: true
},
username: {
type: String,
unique: true,
},
series: {
ref: 'Serie',
type: mongoose.Schema.Types.ObjectId,
autopopulate: {
maxDepth: 1,
select: ['title']
}
}
});
schema.virtual('leagues', {
ref: 'League',
localField: '_id',
foreignField: 'users',
autopopulate: {
maxDepth: 1,
select: ['title', 'engineSize', 'host', 'series']
}
});
The league schema looks like this
const schema: mongoose.Schema = new mongoose.Schema({
_id: {
type: mongoose.Schema.Types.ObjectId,
auto: true
},
title: String,
series: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Serie',
},
users: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
}]
});
This was my solution to checking against multiple fields in mongoose using a getter.
schema.virtual('motoduel').get(function () {
return motoduelModel.findOne({
event: this.series.upcomingEvent._id,
riderGroup: this.riderGroup._id
});
});

How do I pass an object element in express using Mongo?

I want to pass a whole object from an ejs template
For example:
var schema = ... {
Name: [{
}]
}
With this you can achieve it, hope that's what you ask...
notifications: {
notifiId: {type: Schema.Types.ObjectId, ref: 'Notifications' },
viewed: { type: Number, default: 0 }
},
and to find it:
model_Variable.findById(req.params.id).populate("notifiId").exec(function (err,
callBack) {});
Source: How to populate in this case Mongoose

How to rename path in response for populate

I have a query like this:
galleryModel.find({_id: galleryId})
.populate({
model: 'User',
path: 'objectId',
select: 'firstName lastName'
})
End response for objectId will be like this:
objectId: {
...
}
How can I change it to user in response without changing real path?
You can do this by virtual populate, introduced in mongoose version 4.5 . For that you need to define a virtual field in mongoose schema.
var GallerySchema = new mongoose.Schema({
name: String,
objectId: {
type: mongoose.Schema.Types.ObjectId
},
});
GallerySchema.virtual('user', {
ref: 'User',
localField: 'objectId',
foreignField: '_id'
});
Ans when you run find query, just populate it with user.
Gallry.find({_id: galleryId}).populate('user','firstName lastName').exec(function(error, gallery) {
console.log(error);
console.log(gallery);;
});
Above code is not tested in program, there may be typos, You can get more details about mongoose virtual populate on below link
http://mongoosejs.com/docs/populate.html

Populate mongoose array of objects

I have a mongoose model that looks like this:
var ModuleSchema = new Schema({
systems: [{
system: {
type: Schema.ObjectId,
ref: 'System'
},
quantity: {
type: Number
}
}]
});
mongoose.model('Module', ModuleSchema);
Basically the ModuleSchema.systems.$.system property will not get populated.
The property belongs to an object in the array of objects. I have tried everything to get it to populate but it just won't happen.
I tried the following syntax for populating but not sure what might be wrong because I still don't get back the populated System property.
Module.findOne({project: pId}).sort('-created')
.populate('systems.system')
It wont work as system is not a property of systems. You need to populate it like
Module.findOne({project: pId}).sort('-created')
.populate('systems.0.system').exec(function (err, doc){})
Module.findOne({project: pId}).sort('-created')
.populate('systems.1.system').exec(function (err, doc){})
So you should have a for loop and iterate over it to populate all the documents. Else you should modify your model to make it work better.
var ModuleSchema = new Schema({
systems: [{
system: {
type: Schema.ObjectId,
ref: 'System'
},
quantity: {
type: Number
}
}]
});
Change your model to this and it will make easy for you.
var ModuleSchema = new Schema({
systems: {
system: [{
type: Schema.ObjectId,
ref: 'System'
}],
quantity: {
type: Number
}
}
});

Resources