I want to decrease previours quantity by 1 how can I do this in Node Js Mongo Db
Here is my code:
app.put('/quantityUpdate',async(req,res)=>{
const id = req?.body?.id;
const dec= req?.body?.dec;
const filter = {_id:ObjectId(id)}
// this option instructs the method to create a document if no documents match the filter
const options = { upsert: true };
const updateDoc = {
$set: {
quantity: //I'm stuck in this place
},
};
const result = await products.updateOne(filter, updateDoc, options);
return res.send(result);
})
Instead of $set use $inc. It increments a field by a specified value.
To decrease the value by 1 you change your code to:
const updateDoc = { $inc: { quantity: -1 } }
To get more details, checkout the documentation.
Related
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.
I am trying to sort orders in descending and start after on particular key but its not working
nextAfter : -Mk4-n5BnVpwhum62n2g or any Key / _id
db record:
{
'-Mk4-n5BnVpwhum62n2g': {
_id: '-Mk4-n5BnVpwhum62n2g',
createdAt: -1632171667626,
name: 'abc'
},
'-Mk40Ko9DbSeMdjIpY4': {
_id: '-Mk40Ko9DbSeMdjIpY4',
createdAt: -1632171809831,
name: 'new '
}
}
trying query :
query = dbRef.orderByChild('createdAt').startAfter(nextAfter).limitToFirst(limit);
The startAfter() method accepts two parameters - the first is the relevant orderBy value and the second is the optional key of the last entry (for when multiple entries have the same value for the orderBy criteria). So to correctly paginate the reference, you need to pass the previous entry's createdAt value and its key.
const baseQuery = dbRef
.orderByChild('createdAt')
.limitToFirst(limit);
let pageCount = 0, lastChildOnPage = undefined;
const children = [];
while (true) {
const pageQuery = pageCount === 0
? baseQuery
: baseQuery
.startAfter(lastChildOnPage.createdAt, lastChildOnPage.key);
const pageSnapshot = await pageQuery.once('value');
pageSnapshot.forEach((childSnapshot) => {
children.push({ key: childSnapshot.key, ...childSnapshot.val() });
})
const newLastChildOnPage = children[children.length-1];
if (lastChildOnPage !== newLastChildOnPage) {
lastChildOnPage = newLastChildOnPage;
pageCount++;
} else {
break; // no more data
}
}
console.log(`Grabbed ${pageCount} page(s) of data, retrieving ${children.length} children`);
I have this query to display in a table on frontend so I used paginate which is working fine
tableSchema.statics.getn = (query, options) => {
return mongoose.model(MODEL_NAME).paginate(query, options);
};
But when I am trying to perform search query then I am unable to perform paginate on that. Is there any way to send response as paginated form to all the searched queries
I tried following code
tableSchema.statics.search = query => {
const Id = Number(query);
const isNumeric = value => /^\d+$/.test(value);
if (!isNumeric(query)) {
if (query.includes("#")) {
const regex = new RegExp(query, "i");
return mongoose.model(MODEL_NAME).find({ "recipies.to": regex }).paginate(query);
}
return mongoose.model(MODEL_NAME).find({ "temp.name": query });
}
return mongoose.model(MODEL_NAME).find({ recipies: { Id } });
};
It is throwing me error that paginate is not a function. I tried storing find query result in object then performed paginate still it was not working.
I am using "mongoose-paginate-v2" for pagination
Hi I think you missed to add pagination pluging in model section.
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
const mySchema = new mongoose.Schema({
/* your schema definition */
});
mySchema.plugin(mongoosePaginate);
const myModel = mongoose.model('SampleModel', mySchema);
myModel.paginate().then({}); // Usage
You need to add mongoosePaginate in model as plugin.
let options = {
sort: { createdOn: 1 },
page: 1,
limit: 10
};
ModelName.paginate({ 'recipies.to': 'value' }, options, function (err, result) {
if (err) {
console.log(err);
} else {
// Here you will get paginate array please console and check
console.log(result);
}
Here is my code, I want to increment the total no of counts as soon as any user gives the rating. But the $inc command is not running and result is showing the default value which I set zero.
The given is my Schema.
const mongoose = require('mongoose');
const schema = mongoose.Schema;
let Rating = new schema({
user_id:{
type:mongoose.Types.ObjectId
},
stars:{
type:Number
},
ratingCount:{
type:Number,
default:0
}
})
const rating = mongoose.model('Rating', Rating);
module.exports = rating;
This is the function where I want to increment the value.
const express = require('express');
const Router = express.Router();
let Rating = require('../model/rating');
Router.route('/add/:userid').post((req,res)=>{
new Rating({
user_id: req.params.userid,
$inc: {ratingCount:1},
stars: req.body.stars
})
.save()
.then(rating=>res.send(rating))
.catch(err=>console.log(err));
});
module.exports = Router;
Result showing default value of ratingCount.
You need not to use .save() instead you can simply use .findOneAndUpdate() with option { new: true } to return updated document, if it doesn't find any matching document .findOneAndUpdate() will return null.
Code :
const express = require("express");
const Router = express.Router();
let Rating = require("../model/rating");
Router.route("/add/:userid").post((req, res) => {
Rating.findOneAndUpdate(
{ user_id: req.params.userid },
{ $inc: { ratingCount: 1 }, stars: req.body.stars },
{ new: true }
)
.then((rating) => res.send(rating))
.catch((err) => console.log(err));
});
module.exports = Router;
Usually .save() will track changes to document which is returned from find call. Otherwise if it's not the mongoose document returned from .find() call if it's the mongoose object which you're forming like what you're doing now then if it finds _id in object it will update the matching doc else if no matching doc exists with _id or no _id present in request it will insert the new document.
I am trying to update a document in mongo with mongoose using updateOne method:
const updateResult = await UserModel.updateOne({
_id: mongoose.Types.ObjectId(userId)
}, {
$set: {
a: 'B'
}
})
userId contains a string of the ID of the user.
I have tried using the following
1. { _id: userId }
2. { email: theEmailOfTheUser }
But still, the updateResult is
n:0, nModified:0, ok:0
So I think it's must be something with the method itself and not in my query.
Also, when I'm trying to find the user using the query below, it can find it:
const user = await UserModel.find({
_id: userId
});
//user is found
Actually mongoose takes care of the $set and you do not have to add it. just:
const updateResult = await UserModel.updateOne({
_id: userId
}, {
a: 'B'
})
but the better solution would to just use findByIdAndUpdate():
const updateResult = await UserModel.findByIdAndUpdate(userId, {
a: 'B'
})