How to make a nested Schema in Nodejs - node.js

name:"salman,
protein:23,
carbs:23,
calorie:1221,
fats:12,
ingredients:{
salt:1 teaspoon,
......
}
I want a schema like this how can I make a schema of this with nodejs mongoose
also how can i add data in this nested schema because am getting error

Initially you have to create the table schema like this:
const mongoose = require('mongoose');
// Health Schema
const HealthSchema = new mongoose.Schema({
name: {
type: String,
},
protein: {
type: String,
},
carbs: {
type: String,
},
calorie: {
type: String,
},
fats: {
type: String,
},
ingredients: {
type: object,
default: {
salt: '',
fibre: ''
}
},
});
module.exports = mongoose.model(
'health',
HealthSchema
);
Here ingredients objects have priorly set the keyname. So you have to just pass the value at the time of creation.

I'm gonna skip alot of things here.
In your schema do something like,
ingredients:[String]
when creating new data do something like
const healtData= await new healtData({... the data here})
the do something like this before calling save
healthData.ingredients.push(ingredient)
healthData.save()

Related

How to rename a collection without loosing data of collection in Mongoose

I am using Mongoose in my NodeJs project. I want to rename my collection from OldCollectionName to NewCollectionName.
I tried following:
Mongoose.connection.collection('OldCollectionName').rename('NewCollectionName');
But this is making my collection empty. Can someone suggest how can I change the collection name without loosing my collection data? I need all the data from OldCollectionName in NewCollectionName as well.
I have following schema for my model
const Mongoose = require('mongoose');
const mongooseSequence = require('mongoose-sequence');
const Schema = Mongoose.Schema;
var collectionSchema = new Schema({
collectionIdAutoIncrement: { type: Number,unique: true,index:true,sparse:true},
fieldName: {
type: String,
default: ''
},
otherCollectionId: {
type: Schema.Types.ObjectId,
required: true,
ref: "OtherCollection",
},
created: { type: Date, default: Date.now },
updated: { type: Date},
});
collectionSchema.plugin(mongooseSequence, { inc_field: 'collectionIdAutoIncrement' });
var oldCollection = Mongoose.model('OldCollectionName', collectionSchema);

Find Object and Update by pushing to nested Array in MongoDb

I have created a Mongoose Model which holds nested arrays exercises>history>data. I want to make a put request and push an Object, consisting of the time the data was createdAt as well as an array of the Users data to the history of the exercise that was run. However, the following attempt did not work:
User.findOneAndUpdate(
{ _id: req.user.id, "exercises.title": req.body.exercise_title },
{ $push: { "exercises.$.history": { data: [1,2,3,4,5] } } }
);
My Schema looks as follows:
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
userName:{
type: String,
required: true},
exercises:[{
title:{
type: String,
},
history: [{
createdAt: {
type: Date,
default: Date.now
},
data: []
}]
}]
});
module.exports = mongoose.model('User', UserSchema)
I have no clue why my query is not working

How to sort in mongoose by specific order?

I have Mongoose model:
const mongoose = require('mongoose')
const { Schema } = mongoose
const schema = new Schema({
Name: { type: String },
Category: { type: String },
Price: { type: Number }
})
module.exports = mongoose.model('Product', schema)
And I have to sort by Category field. Sort order is
['Clothes', 'Accessories', 'Footwears']
How cat I do it?
The MongoDB server doesn't offer any way to provide a custom sort function.
Javascript does, so you can get the results from the query as an array, and use a custom compare function with Array.sort
I solved it by adding weight of Category. Now my model is like this:
const schema = new Schema({
Name: { type: String },
Category: { type: String },
CategoryWeight: { type: Number },
Price: { type: Number }
})
And I sorting like this:
const products = await Product.find().sort('-CategoryWeight')

Is there a way to query a document based on a subdocument object ref?

Suppose we have a schema that looks like this:
const RandomSchema = new Schema({
name: String,
randomField: String,
subDoc: {
name: String,
refDoc: {
type: Schema.Types.ObjectId,
ref: 'OtherModel',
required: true,
},
},
}, options);
Our OtherModel has a schema that looks like this:
const OtherModel = new Schema({
name: String,
funFact: String,
}, options);
From the front end of my application I'd like to query the RandomSchema model and return all instances of this model where subDoc.refDoc.funFact === someValue.
Is this possible? I know we have ways to populate those subdocs when return them but it happens only after matching docs have been returned, when in this case we'd need to know more than just the objectId of refDoc.
If multiple collections are involved, this task requires use of aggregation pipeline.

Nest mongoose schema within itself?

Is it possible with mongoose to create a schema, call it Folders and it has a property within called subfolders that is an array of nested Folder subdocs?
const mongoose = require('mongoose')
let SubSchema = mongoose.Schema({
name: { type: String, required: true }
})
let FolderSchema = mongoose.Schema({
name: { type: String, required: true },
children: [ SubSchema ]
})
I know I can nest subdocs in an array by referencing another schema similar to what is shown above. What I'm looking to do though is reuse FolderSchema within itself. Obviously this causes an issue because at the time of creation of the schema, FolderSchema doesn't exist. Is there a better way to do this? Is there a way to recursively nest documents using the same schema?
I know I could have the array be a list of ObjectId that reference a collection but I was hoping to just keep it all nested as documents. I guess if I did populate() to let it resolve the doc ids, that would essentially be the same thing. Just wondering if there is another method I wasn't aware of.
I haven't tried this personally, but I have read this can be achieved by simply referencing this in the field you want to reference the current model.
The model you would like to will look something like this,
const mongoose = require('mongoose')
const FolderSchema = mongoose.Schema({
name: { type: String, required: true },
type: { type: String, enum: ['file', 'directory'],
children: [ this ]
})
const FolderModel = mongoose.model('Folder', FolderSchema);
Hope that helps!
look you need to clarify your question a little bit but as much as i understood from the question, yes it can be done in this way :
var mongoose = require('mongoose');
var FolderSchema = new mongoose.Schema({
SubFolders = [ type:monogoose.Schema.Types.ObjectId, ref : 'Folders']
});
var folder = mongoose.model('Folders',FolderSchema);
module.exports = folder;
This shall work for you.
So for infinite object having children, I did it like so:
mongoose schema:
const itemSchema = new mongoose.Schema({
name: String,
items: {
type: [this],
default: undefined
}
}, { _id: false })
const mainSchema = new mongoose.Schema({
name: String,
items: {
type: [itemSchema],
default: undefined
}
})
output example:
[
{
_id: '62a72d6915ad7f79d738e465',
name: 'item1',
items: [
{
name: 'item1-item1',
items: [
{
name: 'item1-item1-item1'
},
{
name: 'item1-item1-item2'
},
{
name: 'item1-item1-item3'
},
]
},
{
name: 'item1-item2'
}
]
},
{
_id: '62a72d6915ad7f79d738e467',
name: 'item2'
},
{
_id: '62a72d6915ad7f79d738e467',
name: 'item3',
items: [
{
name: 'item3-item1'
}
]
}
]

Resources