Auto increment in MongoDb is not working in Express NodeJS - node.js

exports.addToCart = async(req,res)=>{
const cart = await schema.cart.findOne({username:req.body.username})
if(cart){
return res.status(404).json({
message:"User's cart is already available, append to the same cart"
})
}
else{
const cart = new schema.cart({
cartId : getValueForNextSequence("item_id"),
username : req.body.username,
productsInCart :req.body.productsInCart
});
console.log(cart.cartId);
await cart.save();
res.status(200).json(cart)
}
}
async function getValueForNextSequence(sequenceOfName){
const sequenceDoc = await schema.counter.findOneAndUpdate(
{"_id": sequenceOfName },
{"$inc":{"sequence_value":1}},
);
return sequenceDoc.sequence_value;
}
THis is the schema for counter I added a document with _id as item_id and sequence_value as 0
const counterSch = new mongoose.Schema({
_id :{
type : String
},
sequence_value:{
type : Number
}
})
getValueForNextSequence method is not returning any value I dont know why please help with this issue.Here I have to increment the cartId automatically but its not happening

Related

Store Product Detail in an array using mongoDB

import mongoose from 'mongoose'
const Register_user = mongoose.Schema({
Gender : String,
name : String,
dob : String,
weight : String,
height : String,
userEmail : String,
cart : Array
})
const register_schema = mongoose.model("User_registration" , Register_user)
export default register_schema;
// ^ Add to Cart
export const addToCart = async (req,res) =>
{
try {
// ^ Product Data (actually item data that user added to cart) now need to save this in cart array
const Data = req.body.item;
// ^ to match user Email and cart Data in only and only his cart array
const email = req.body.userEmail;
// ^ finding User based on email
const user = await registerSchema.findOne({userEmail : `${email}`})
if(user)
{
// ^ successfully got the user and his cart
const {cart} = user;
}
} catch (error) {
console.log(`error in adding item to cart + ${error.message}` )
}
}
I want to store item details in cart Array , whatever item user added to cart i want to store it in mongodb cart[] is there a specific method to do this? I tried safe() doesn't work for me
I fixed it by getting an id of a document and using the findByIdAndUpdate method.
if (user) {
// ^ successfully got the user and his cart
const { _id } = user;
console.log(_id);
const { cart } = user;
await registerSchema.findByIdAndUpdate(_id, { cart: [...cart, Data] }).then('done babe');
}

how to check number of documents insert in MongoDB with Mongoose in console.log

I just begin to learn how to use MongoDB and Mongoose, So I try to insert some docs in MongoDB running locally, this is how i do it when I use only MongoDB driver :
const { MongoClient } = require("mongodb");
const uri = "mongodb://localhost:27017";
const client = new MongoClient(uri);
async function run() {
const dbName = client.db("fruitsDB");
try {
await client.connect();
// I insert the function to insert the docs here
await insertMultiDocs(dbName, docs);
// Establish and verify connection
await client.db("admin").command({ ping: 1 });
console.log("Connected successfully to server");
} finally {
await client.close();
}
}
run().catch(console.dir);
// below is the docs I want to insert and the function I use like the MongoDB's
// documentation.
const docs = [
{ name: "Ananas", rating: 7, review: "nice fruit"},
{ name: "Prune", rating: 8, review: "Kinda good"},
{ name: "Peach", rating: 7, review: "taste great"},
{ name: "Strawberry", rating: 9, review: "great fruit"}
];
async function insertMultiDocs (client, newList) {
try {
const insertManyresult = await client.collection("fruits").insertMany(newList);
let ids = insertManyresult.insertedIds;
console.log(`${insertManyresult.insertedCount} documents were inserted.`);
for (let id of Object.values(ids)) {
console.log(`Inserted a document with id ${id}`);
}
} catch(e) {
console.log(`A MongoBulkWriteException occurred, but there are successfully processed documents.`);
let ids = e.result.result.insertedIds;
for (let id of Object.values(ids)) {
console.log(`Processed a document with id ${id._id}`);
}
console.log(`Number of documents inserted: ${e.result.result.nInserted}`);
}
}
Then I get this console.log :
4 documents were inserted.
Inserted a document with id 63051aeb6b883a87e46ea895
Inserted a document with id 63051aeb6b883a87e46ea896
Inserted a document with id 63051aeb6b883a87e46ea897
Inserted a document with id 63051aeb6b883a87e46ea898
Connected successfully to server
Now I want to try to do the same with Mongoose :
const mongoose = require("mongoose");
const { Schema } = mongoose;
main().catch(err => console.log(err));
async function main() {
try {
await mongoose.connect("mongodb://localhost:27017/fruitsDB");
const fruitSchema = new Schema({
name : String,
rating : Number,
review : String
});
const Fruit = mongoose.model("Fruit", fruitSchema);
// I insert the docs here...
Fruit.insertMany(docs)
} catch (error) {
console.log(error);
}
}
It work, however is there a way to implemente the console.log in Mongoose and loop through each document inserted like the way it did on MongoDB drive ?
insertMany returns the documents that are added to DB post the validation (if any validations are set in place).
You can just .length on it to get the value like this
const insertManyresult = await Fruit.insertMany(docs);
console.log(`${insertManyresult.length} documents were inserted.`);
Since you have access to all the documents. You can perform any operation of choice (loop over every document, get length etc.)
Read more about insertMany here.

Not able to find the right Document

I am a working on a project for my school. I want to delete employees in the database. This can be done by setting the attribute isDeleted to true.
isDeleted : {
type : Boolean,
default :false,
required : true
}
and the controller function:
const deleteEmployee = async(req, res)=>{
try{
const employeeID = req.body.id;
console.log(employeeID);
const employee = await Member.findByIdAndUpdate(employeeID, {isDeleted : true}, {new : true});
res.status(200).json(employee)
}catch(err){
console.log(err);
}
}
I am not able to update the database. Please suggest changes.

Query was already executed

I want to calculate averageRating from my reviews collection. So, firstly I make an aggregation pipeline to find the avgRating and ratingQuantity by matching with item ID.
Then I make an post middleware(document middleware) and when any one create a new review then the averageRating and ratingQuantity fields are get updated, but the problem is that this only works on save not on update or delete. So, i make a query middleware and then for getting the document I execute the query but got error Query was already executed Please Help!!!
My reviewModel.js code
const mongoose = require('mongoose');
const movieModel = require('./movieModel');
const reviewSchema =new mongoose.Schema({
review:{
type:String,
required:[true,"review can't be blank"],
maxlength:100,
minlength:10
},
rating:{
type:Number,
required:[true,"review must have a rating"],
max:10,
min:1
},
movie:{
type:mongoose.Schema.ObjectId,
ref:'movies',
required:[true,'review must belong to a movie']
},
user:{
type:mongoose.Schema.ObjectId,
ref:'users',
required:[true,'review must belong to a user']
}
},
{
toJSON:{virtuals:true},
toObject:{virtuals:true}
});
reviewSchema.pre(/^find/,function(next){
this.populate({
path:'movie',
select:'name'
}).populate({
path:'user',
select:'name'
});
next();
})
reviewSchema.index({movie:1,user:1},{unique:true});
reviewSchema.statics.calcAvgRating = async function(movieId){
console.log(movieId);
const stats = await this.aggregate([
{
$match:{movie:movieId}
},
{
$group:{
_id:'$movie',
nRating:{$sum:1},
avgRating:{$avg:'$rating'}
}
}
])
console.log(stats);
const movie = await movieModel.findByIdAndUpdate(movieId,{
ratingsQuantity:stats[0].nRating,
avgRating:stats[0].avgRating
});
}
reviewSchema.post('save',function(){
this.constructor.calcAvgRating(this.movie);
})
reviewSchema.pre(/^findOneAnd/,async function(next){
const r = await this.findOne();
console.log(r);
next();
})
const reviewModel = mongoose.model('reviews',reviewSchema);
module.exports = reviewModel;
My updateOne controller
exports.updateOne = Model=> catchAsync(async(req,res,next)=>{
console.log("handler");
const doc = await Model.findByIdAndUpdate(req.params.id,req.body,{
new:true,
runValidators:true
});
if(!doc)
return next(new appError('Ooops! doc not found',404));
sendResponse(res,200,'success',doc);
})
Try this
reviewSchema.post(/^findOneAnd/,async function(doc){
const model=doc.constructor;
})
Here doc is actually the current executed document and by doing doc.constructor you got its model. On that model you can use the calcAvgRating

Add a deeply embedded document conditionally if unique field value

I have following model and schemas in mongoose :
const Doc = mongoose.model(
"Doc",
new mongoose.Schema({
name: String,
subDocs: [SubDoc],
})
);
const SubDoc = new mongoose.Schema({
name: String,
subSubDocs: [SubSubDoc],
});
const SubSubDoc = new mongoose.Schema({
name: String,
});
This code adds a uniquely named embedded SubDoc to the parent Doc. By "uniquely named" I mean it will not create a subdocument if another subdocument in the parent has the same value for "name":
const createUniqueSubDoc = (docId, name) => {
return db.Doc.findOneAndUpdate(
{ _id: docId, "subDocs.name": { $ne: name } },
{
$push: {
subDocs: {
name: name,
},
},
},
{ new: true, useFindAndModify: false }
);
};
const run = async (doc) => {
let doc = await db.Doc.create({name:"Main document"})
createUniqueSubDoc(doc._id, "sub document name");
};
run();
addToSet doesn't work with dates or id's so I'm $ne as suggested here.
But how do I add a uniquely named embedded SubSubDoc to the already embedded SubDoc's subSubDoc field? You can't query the embedded SubDoc with findOneAndUpdate because it's only a schema not a model like the Doc model.
using MongooseArray methods:
const createUniqueSubSubDoc = async function (docId, subDocId, subSubDoc) {
const doc = await db.Doc.findById(docId);
const subDoc = doc.subDocs.id(subDocId);
if (subDoc.subSubDocs.find((ssd) => ssd.name == subSubDoc.name))
return "oops! you already gave another SubSubDoc this name";
subDoc.subSubDocs.push(subSubDoc);
await doc.save();
return doc.subDocs.id(subDocId);
};
createSubSubDoc(
"5f56d9621222bbcc3bf4ee41", // the id for a Doc
"5f56d9631222bbcc3bf4ee42", // the id for a SubDoc of that Doc
{ name: "subSubDoc name" } // the object for the new SubSubDoc
);
git repo

Resources