How to CRUD data in mongoose without data modeling - node.js

i was searching internet for 2 days now and did not find any answer,
const mongoose = require('mongoose');
const channelsSchema = new mongoose.Schema(
{
stateName: {
type: String,
required: [true, 'A state must have a name'],
unique: true,
index:true
},
id: {
type:String
},
Name: {
type:String
},
**anyThing: [Object]
},
{ strict: false }
);
const Channels = mongoose.model('Channels', channelsSchema);
module.exports = Channels;
is there any way to **anything accept anything?
note: its not a big project and im not worried about the security. it runs only localy

You can pass {strict: false} as second argument to the Schema to achieve this.
const mongoose = require('mongoose');
const channelsSchema = new mongoose.Schema({}, {strict: false})
const Channels = mongoose.model('Channels', channelsSchema);
module.exports = Channels;

Related

mongoose population (refs) is not working

I have created two models where I am trying to ref one model to another but it's not working and I don't have any idea about it I used it exactly the same way as in the mongoose example but it is not helping, the only difference between my working and their example is I have two different files for both models and I am exporting them to use in another file
The example I took reference from Mongoose
First Model
const userModel = require('./userModel')
const {Schema} = mongoose
const tweet = new Schema({
date: {
type: Date,
required: true,
},
msg:{
type: String,
maxlength:140,
required:true
},
tweetid:{
type: mongoose.Types.ObjectId
}
})
const tweetSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'userModel'
},
tweets: {
type: [{tweet}],
default: []
}
})
const tweetModel = mongoose.model('tweet',tweetSchema)
module.exports = tweetModel
Second Model
const {Schema} = mongoose
const userSchema = new Schema({
email: {
type:String,
required: true,
unique: true,
trim:true
},
password: {
type:String,
required: true,
trim:true
},
follows: {
type: [String],
default: []
}
})
const userModel = mongoose.model("User",userSchema)
module.exports = userModel
Your reference string should be equal to the model name that you have passed to mongoose.model:
const tweetSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'User'
},
tweets: {
type: [{tweet}],
default: []
}
})

How do I update an object in Post Model from the User Model using Mongoose, Node.js and React.js?

I am still on this issue and I have implemented so far what I have seen online, still not working. I have two models named: PostSchema and UserSchema. PostSchema and Userschema both have a field called 'username'. So, I have created action that enables the user to update their profile. The challenge I have now is that the update made by the user which is stored in the UserSchema does not reflect on the PostSchema. For instance, I would like the username on the PostSchema to be updated to the current username on the UserSchema was the user updates or change their name from the UserSchema. I am trying to use the ref and populate features in mongoose. Probably, I am not doing it the right way.
With the current codes I have now, the posts are not fetching. If I remove the populate(' username', 'username').exec() line, it will fetch but the post.username will not change to user.username coming from the UserSchoma model.
Here are my codes:
I am still new and still learning, kindly help me pass this stage.
UserSchema model
const mongoose = require("mongoose"); //import mongoose
const UserSchema = new mongoose.Schema({
username:{ //I want the username here to update to post model too
type: String,
required: true,
unique: true
},
email:{
type: String,
required: true,
unique: true
},
password:{
type: String,
required: true
},
profilePicture:{
type: String,
default: "",
},
}, {timestamps: true}
);
//exporting this schema
module.exports = mongoose.model("User", UserSchema);
PostSchema model
const mongoose = require("mongoose"); //import mongoose
const Schema = mongoose.Schema;
const PostSchema = new mongoose.Schema(
{
title:{
type: String,
required: true,
unique: true
},
description:{
type: String,
required: true,
},
postPhoto:{
type: String,
required:false,
},
username:{ //this should reference user.username
type: Schema.Types.ObjectId, ref: 'User',
required: true,
},
categories:{
type: Array,
required: false
},
}, {timestamps: true}
);
//exporting this schema
module.exports = mongoose.model("Post", PostSchema);
This is where I am getting the posts
//Get Post
router.get("/:id", async(req, res)=>{
try{
const post = await Post.findById(req.params.id);
populate(' username', 'username').exec()
res.status(200).json(post)
}catch(err){
res.status(500).json(err)
}
})
This is the client side code with React.js where I called the posts from the api
import { useLocation } from 'react-router';
export default function SinglePost() {
const location = useLocation()
const path = location.pathname.split("/")[2];
const [post, setPost] = useState({});
const [title, setTitle] = useState("")
const [description, setDescription] = useState("");
const [updateMode, setUpdateMode] = useState(false)
useEffect(() => {
const getPost = async () => {
try{
const response = await axios.get("/posts/"+path )
setPost(response.data);
setTitle(response.data.title);
setDescription(response.data.description);
setPostUser(response.data.username)
}catch(err){
}
};
return getPost()
}, [path]);
use $lookup and aggregation
aggregate object is like this
Post.aggregate([
{ $match: { _id: req.params.id } },
{
$lookup: {
from: "User",
localField: "username",
foreignField: "_id",
as: "username",
},
},
]).exec()

node mongoose update two collections

I have two schemas, a "projects" schema, and an "applications" schema.
What is the most efficient way of creating a new entry in a collection and updating an existing entry in another collection based on data inside the new entry? Can I avoid making multiple API requests and somehow run a "stored procedure" on the mongoDB end to handle updating the Projects collection when there is a change in the Applications collection?
In this scenario, ideally when an application for a project is created, a new entry is created in the Applications collection and the Project in the Projects collection is updated to reflect the information in the Application.
Can I do this without making multiple api requests?
Project Schema:
// models product.js
const mongoose = require('mongoose');
const { ObjectId } = mongoose.Schema;
const projectSchema = new mongoose.Schema({
name: {
type: String,
trim: true,
required: true,
maxlength: 32
},
applications: {
type: Number,
default: 0
},
created_by: {
type: ObjectId,
ref: 'User'
},
applicants: {
type: Array,
default: []
}
}, {timestamps: true}
);
module.exports = mongoose.model("Project", projectSchema);
Application Schema:
const mongoose = require('mongoose');
const applicationSchema = new mongoose.Schema({
applicantId: {
type: ObjectId,
ref: 'User'
},
ownerId: {
type: ObjectId,
ref: 'User'
},
projectId: {
type: ObjectId,
ref: 'Project'
}
}, {timestamps: true});
module.exports = mongoose.model("Application", applicationSchema);
Note that these are separate schemas because they each carry around 15 fields, i've trimmed them down to post this question.
I suggest to use hooks for mongoose model, there is a post save hook which you can use on Application model to update Project and increment application count.
EDIT - Added Pseudo Code
Project Model
// models -> project.js
const mongoose = require('mongoose');
const {
ObjectId
} = mongoose.Schema;
const projectSchema = new mongoose.Schema({
name: {
type: String,
trim: true,
required: true,
maxlength: 32
},
applications: {
type: Number,
default: 0
},
created_by: {
type: ObjectId,
ref: 'User'
},
applicants: {
type: Array,
default: []
}
}, {
timestamps: true
});
projectSchema.statics = {
/**
* Find project by _id
*
* #param {ObjectId} _id
* #api private
*/
get: function (_id) {
return this.findOne({
_id
})
.exec();
}
}
module.exports = mongoose.model("Project", projectSchema);
Application Model
const mongoose = require('mongoose');
const projectModel = require("./project")
const applicationSchema = new mongoose.Schema({
applicantId: {
type: ObjectId,
ref: 'User'
},
ownerId: {
type: ObjectId,
ref: 'User'
},
projectId: {
type: ObjectId,
ref: 'Project'
}
}, {
timestamps: true
});
// Async hook
applicationSchema.post('save', function (doc, next) {
const relatedProject = projectModel.get(doc.projectId);
relatedProject.applications++;
relatedProject.save();
next();
});
module.exports = mongoose.model("Application", applicationSchema);

How do I index a field on a mongoose Schema that uses a discriminator?

The error started after I started using the discriminator.
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const Base = require("../config/Base");
const Refill = Base.discriminator(
"Refill",
new Schema({
cylinderSize: { type: Number, required: true },
cylinderSwap: { type: Boolean, required: true },
quantity: { type: Number, required: true },
location: {
type: { type: String },
coordinates: [Number]
}
})
);
Refill.index({ location: "2dsphere" });
module.exports = mongoose.model("Refill");
This returns the error Refill.index is not a function
In Mongoose, indexes must be created on schemas, not models. In your case, the Refill object is a model. One approach is to implement this in three steps:
Create the schema
Add the index to the schema
Create the model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const Base = require("../config/Base");
const refillSchema =
new Schema({
cylinderSize: { type: Number, required: true },
cylinderSwap: { type: Boolean, required: true },
quantity: { type: Number, required: true },
location: {
type: { type: String },
coordinates: [Number]
}
});
refillSchema.index({ location: "2dsphere" });
const Refill = Base.discriminator("Refill", refillSchema);
module.exports = mongoose.model("Refill");
I just took out the Refill.index({ location: "2dsphere" }); and the rest of my code is working fine apparently indexing that field wasn't necessary.

Referencing Schemas in Mongoose

I have a couple models that are in going to be held in separate files and I can't seem to find a way to reference them without resorting to having them in the same file.
My first file contains the following:
var mongoose = require('mongoose'),
bcrypt = require('bcrypt'),
Schema = mongoose.Schema;
var UserSchema = new Schema({
email: {
type: String,
unique: true,
lowercase: true,
trim: true,
required: true
},
hash_password: {
type: String
},
/* etc */
});
UserSchema.methods.comparePassword = function(password) {
return bcrypt.compareSync(password, this.hash_password);
};
module.exports = mongoose.model('User', UserSchema);
And the second file is this:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ThreadSchema = new Schema({
title: {
type: String,
required: true,
trim: true
},
created_by: {
type: { type: Schema.Types.ObjectId, ref: 'User' },
required: true
}
/* etc */
});
module.exports = mongoose.model('Threads', ThreadSchema);
I keep getting this error: "TypeError: Undefined type undefined at created_by.required". The code works if I keep the user and thread models in the same file but when I separate the files, they no longer can reference each other. I tried adding require('./userModel') at the top of the threadModel but that didn't work either.
Any help is appreciated.

Resources