How to ref nested ObjectId in mongoose schema - node.js

This is my category schema where i have nested nestedCategorySchema and I want to refer to this ObjectId of this in other collection
`
const mongoose = require("mongoose");
const { Schema } = mongoose;
const nestedCategorySchema = new Schema({
name: {
type: Schema.Types.ObjectId,
},
});
const categorySchema = new Schema(
{
clientname: {
type: Schema.Types.String,
},
categoryOne: {
type: [nestedCategorySchema],
default: [],
},
categoryTwo: {
type: [nestedCategorySchema],
default: [],
},
},
{
timestamps: true,
}
);
exports.default = mongoose.model("category", categorySchema);
mongoose.model("category").collection.createIndex({
clientname: 1,
});
`
In another collection I want to refer the nested categoryOne ObjectId
`
const mongoose = require("mongoose");
const { Schema } = mongoose;
const prodSchema = new Schema(
{
categories: [
{
_id: false,
clientname: {
type: String,
},
** categoryLevelOne: {
type: mongoose.Schema.Types.ObjectId,
ref: "category.categoryOne",
},**
},
],
},
{
timestamps: true,
}
);
`
In prodSchema I want to refer to nested categoryOne

Try to declare the nestedCategorySchema as a model:
mongoose.model("nestedCategory", nestedCategorySchema);
And change the the categoryOne attribute in categorySchema to a ObjectId ref:
categoryOne: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'nestedCategory',
default: []
}];
Finally, given your configuration, you should probably change the categories property in prodSchema to a ref itself:
const prodSchema = new Schema(
{
categories: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'category'
},
],
},
{
timestamps: true,
}
);
In mongoose you can only create references to ObjectIds.

Related

How to push items in to an array which was referenced in collections schema in mongoose, nodejs

i want to create an item and push it into items array which was referenced in my collections schema. What i am sending in the payload is item properties and collection id. But i am getting CastError. Please help
COLLECTION SCHEMA
const collectionSchema = new Schema(
{
name: { type: String },
description: { type: String },
owner: { type: Schema.Types.ObjectId, ref: "User" },
items: [{ type: Schema.Types.ObjectId, require: true, ref: "Item" }],
},
{ timestamps: true }
);
export default model("Collection", collectionSchema);
ITEM SCHEMA
import mongoose from "mongoose";
const { Schema, model } = mongoose;
const itemSchema = new Schema(
{
name: { type: String },
description: { type: String },
owner: { type: Schema.Types.ObjectId, ref: "User" },
likes: [{ type: Schema.Types.ObjectId, ref: "User" }],
collections: { type: Schema.Types.ObjectId, ref: "Collection" },
},
{ timestamps: true }
);
export default model("Item", itemSchema);
CREATE ITEM ROUTE
itemRouter.post("/", JWTAuthMiddleware, async (req, res, next) => {
const item = new ItemModal(req.body)
const collection = await CollectionModal.findByIdAndUpdate(
req.user._id,
{
$push : { items: [{ ...req.body, id: item._id }] },
},
{ new: true }
);
res.send(collection);
});
What i am getting is an CASTERROR

How to populate a data for a field in mongoose, where reference is a nested array in model?

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

Add timestamp to a new subdocument or subschema in mongoose

I have this document in mongo atlas
_id: 5f8939cbedf74e363c37dd86,
firstname: "Person",
lastname: "Person lastname",
sex: "Masculino",
age: "20",
birthDay: 2020-10-07T00:00:00.000+00:00,
vaccines: Array
0:Object
dose: Array
_id: 5f8939cbedf74e363c37dd87
vaccine:5f7023ad96f7ed21e85be521
createdAt:2020-10-16T06:12:27.726+00:00
updatedAt:2020-10-16T06:12:27.726+00:00
1:Object
dose:Array
_id:5f893a9ca98e97188c93fea8
vaccine:5f70259796f7ed21e85be523
2:Object
dose:Array
_id:5f893acda98e97188c93fea9
vaccine:5f7023ad96f7ed21e85be521
This is my mongoose schema
const mySchema = new Schema({
firstname: {
type: String,
required: true,
},
lastname: {
type: String,
required: true,
},
sex: {
type: String,
required: true,
},
age: {
type: String,
required: true,
},
birthDay: {
type: Date,
required: true,
},
vaccines: [
{
type: new Schema(
{
vaccine: {
type: Schema.ObjectId,
ref: "Vaccine",
},
dose: Array,
},
{ timestamps: true }
),
},
],
});
every time I add a new person the vaccines array gets one new object with the timestamp as you can see, in my js file I use this code:
const addPerson = (person) => {
const myPerson= new Model(person);
return myPerson.save();
};
Then when I add a new vaccine for the same person this does not get the timestamp, I'm using this code for that:
const addPersonVaccine = async ({ params, body }) => {
if (!params) return Promise.reject("Invalid ID");
const vaccines = [body];
const foundPerson = await Model.updateOne(
{
_id: params,
},
{
$push: {
vaccines: vaccines,
},
}
);
return foundPerson;
};
This is what my body inside vaccines array has:
[ { vaccine: '5f72c909594ee82d107bf870', dose: 'Primera' } ]
The problem is that I have no results about the next timestamps, as you can see in my mongo atlas document:
1:Object
dose:Array
_id:5f893a9ca98e97188c93fea8
vaccine:5f70259796f7ed21e85be523
2:Object
dose:Array
_id:5f893acda98e97188c93fea9
vaccine:5f7023ad96f7ed21e85be521
Is that the best way to implement timestamps in subdocuments or sub schemas?
I will appreciate your answers, thnks 👏
You can use mongoose schema timestamps options to the inner schemas
const mongoose = require("mongoose");
const forumSchema = new mongoose.Schema(
{
title: { type: String, required: true },
biddings: [
{
type: new mongoose.Schema(
{
biddingId: String,
biddingPoints: Number
},
{ timestamps: true }
)
}
]
},
{ timestamps: true }
);
const Forum = mongoose.model("Forum", forumSchema);
module.exports = Forum;
for more Mongoose schema set timestamp on nested document

Product reference is undefiend

I have a model named order. The order model is having a field name product which is a reference to the product model.
My Order model is like
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const { ObjectId } = mongoose.Schema;
const ProductCartSchema = new Schema({
product: {
type: ObjectId,
ref: Product,
},
name: String,
count: Number,
price: Number,
});
const orderSchema = new Schema(
{
products: [ProductCartSchema],
transaction_id: {},
amount: { type: Number },
address: { type: String },
updated: Date,
user: {
type: ObjectId,
ref: User,
},
},
{ timestamps: true }
);
var Order = mongoose.model('Order', orderSchema);
var ProductCart = mongoose.model('ProductCart', ProductCartSchema);
module.exports = { Order, ProductCart };
And my product model schema is like
var mongoose = require(mongoose);
var Schema = mongoose.Schema;
const { ObjectId } = mongoose.Schema;
const productSchema = new Schema(
{
name: {
type: String,
required: true,
maxlength: 32,
trim: true,
},
description: {
type: String,
required: true,
maxlength: 2000,
trim: true,
},
price: {
type: Number,
required: true,
maxlength: 32,
trim: true,
},
category: {
type: ObjectId,
ref: 'Category',
required: true,
},
stock: {
type: Number,
},
sold: {
type: Number,
default: 0,
},
photo: {
type: Buffer,
contentType: String,
},
},
{ timestamps: true }
);
module.exports = mongoose.model('Product', productSchema);
It's giving me error
Product is not defined on order.js line no 7
Am I need to import product model in this if yes then how I can do that and if not then where is the error
In order to use Product reference in your Order.js Schema, you need to import it.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const { ObjectId } = mongoose.Schema;
var Product = require('Product'); <----------------------------------- Import this
const ProductCartSchema = new Schema({
product: {
type: ObjectId,
ref: Product,
},
name: String,
count: Number,
price: Number,
});
const orderSchema = new Schema(
{
products: [ProductCartSchema],
transaction_id: {},
amount: { type: Number },
address: { type: String },
updated: Date,
user: {
type: ObjectId,
ref: User,
},
},
{ timestamps: true }
);
var Order = mongoose.model('Order', orderSchema);
var ProductCart = mongoose.model('ProductCart', ProductCartSchema);
module.exports = { Order, ProductCart };

2dsphere is not a valid type at path `index`

I have 2 schema in mongoose as follows:
PointSchema.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const PointSchema = new mongoose.Schema({
type: {
type: String,
enum: ['Point']
},
coordinates: {
type: [Number]
},
index: {
type: '2dsphere',
sparse: true
}
});
module.exports = {
PointSchema
};
DeviceSchema.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const PointSchema = require('./PointSchema').PointSchema;
const DeviceSchema = mongoose.Schema({
name: String,
location: {
type: PointSchema,
default: null
}
}, {
collection: 'devices',
timestamps: {
createdAt: 'created_at',
updatedAt: 'updated_at'
}
});
module.exports = mongoose.model('Device', DeviceSchema);
Is there some problem in PointSchema.js as it is giving following error:
TypeError: Invalid schema configuration: 2dsphere is not a valid
type at path index.
Followed this documentation to create PointSchema.js: https://mongoosejs.com/docs/geojson.html
I solved my problem with the next configuration in the model!
module.exports = (mongoose) => {
const DomainSchema = new mongoose.Schema({
domain_id: { type: Number },
name: String,
domain_data: {
type: { type: String },
coordinates: { type: Array },
},
});
DomainSchema.index({ domain_data: '2dsphere' });
return mongoose.model('Domain', DomainSchema);
};

Resources