How do I add an entry in an array inside MongoDB - node.js

Below is my code to add an item to an array inside a mongoDB object. I am trying to add a review for my restaurant
The restaurant object looks like:
_id: ObjectID("61723c7378b6d3a5a02d908e")
name: "Hotel"
reviews: Array
reviews.js:
const mongoCollections = require('../config/mongoCollections');
const restaurants = mongoCollections.restaurants;
module.exports = {
async created (restaurantId, title, reviewer, rating, dateOfReview, review) {
const restaurantsCollection = await restaurants();
let newReview = {
restaurantId : restaurantId,
title : title,
reviewer : reviewer,
rating : rating,
dateOfReview : dateOfReview,
review : review
};
const insertInfo = await restaurantsCollection.updateOne( {_id : restaurantId},{$addToSet: {reviews: newReview}} )
if (insertInfo.insertedCount === 0) throw 'Could not add review';
},
index.js:
const restaurantsData = require('./restaurants');
const reviewsData = require('./reviews')
module.exports = {
restaurants: restaurantsData,
reviews: reviewsData
};
seed.js: // to call the function
const dbConnection = require('../config/mongoConnection');
const data = require('../data/');
const restaurants = data.restaurants;
const reviews = data.reviews;
const main = async () => {
await reviews.created("61723c7378b6d3a5a02d908e", "random", "sam", 4, "25/2/2002",
"amazing");
}
main();
I tried to use update instead of updateOne but it shows a deprecated warning

Related

Auto increment in MongoDb is not working in Express NodeJS

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

Mongo DB Update data

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.

Find value inside a collection in mongoose from nested json

Suppose I have data stored in collection Teacher as:
{
"name":"john",
"age":45,
"class_access":{
1234:"head",
1235:"head
},
"_id" : ObjectId("12312312"),
}
{
"name":"henry",
"age":55,
"class_access":{
1234:"head",
},
"_id" : ObjectId("sdf9991"),
}
{
"name":"travis",
"age":35,
"class_access":{
2341:"head",
},
"_id" : ObjectId("sas21"),
}
I want to find all the information of all the teachers belonging to class 1234.
For this I tried:
const TeacherDetails = await Teacher.find({ class_access: {1234:"head"} })
But it doesn't return anything.
So how can I access nested json to get all the details?
If any one needs any further information do let me know.
As per solution provided by Mr. Arif
const TeacherDetails = await Teacher.find({ "class_access.1234": "head" });
Support class value is not constant say I'm getting it from variable
const className = 1234
Now if I try, fetching className, it gives syntax error, I tried following syntax error for all of them
const TeacherDetails = await Teacher.find({ class_access.className: "head" });
const TeacherDetails = await Teacher.find({ class_access[className]: "head" });
const TeacherDetails = await Teacher.find({ 'class_access.+'${className}': "head" });
So how can we do it dynamically?
Since class_access represent object which may have multiple keys, you should try like
You can use [variableName] as key like following
method 1: Using string template
const className = 1234
const TeacherDetails = await Teacher.find({ [`class_access.${className }`]: "head" });
method 2: Using string concatenation
const className = 1234
const classAccess = 'class_access.' + className;
const TeacherDetails = await Teacher.find({ [classAccess] : "head" });

NodeJS Mongoose update document

I'm trying to update or create a document in a MongoDB collection, using "mongoose" this way :
this.statsModel.findOne(
{product_id: requestData.ean},
).then((stats: mongoose.Schema) => {
const productId: string = requestData.ean;
// Update stats with the new scan...
const beforeStats: mongoose.Schema = stats;
const scan: any = {
coords: {
lat: requestData.lat,
lon: requestData.lon,
},
at: new Date(),
};
if (stats) {
stats.scans.push(scan);
stats.update();
} else {
const newStat = new this.statsModel();
newStat._id = requestData.ean;
newStat.product_id = requestData.ean;
newStat.scans = [scan];
newStat.purchases = [];
newStat.save();
}
When this code runs, no new element appears in the "scans" property if had a stats document.
The document is properly created if the stats document was not found.
I tried to change "update()" method to "save()" method, but, this way, i got a "Version error No matching document for the id..."
What i'm doing wrong ?
Regards...
Finally, update the type of the stats promised to Model instead of mongoose.Schema :
this.statsModel.findOne(
{product_id: requestData.ean},
).then((stats: Model<Stats>) => {
const productId: string = requestData.ean;
// Update stats with the new scan...
const beforeStats: mongoose.Schema = stats;
const scan: any = {
coords: {
lat: requestData.lat,
lon: requestData.lon,
},
at: new Date(),
};
if (stats) {
stats.scans.push(scan);
stats.save();
} else {
const newStat = new this.statsModel();
newStat._id = requestData.ean;
newStat.product_id = requestData.ean;
newStat.scans = [scan];
newStat.purchases = [];
newStat.save();
}
So the save() method properly works...
Thx

Mongoose: $inc not working

I am not sure what the problem is, as I've read numerous examples.
Taken from what I was advised here in this StackOverFlow(Mongoose - Increment a value inside an array of objects), I changed the format of poll at ease to accommodate what was recommended.
So I was able to create a document format as so:
{
"_id": "584c4160b3b22e1bdad59bce",
"title": "Food",
"description": "test",
"labelOptions": {
"burger": 29,
"coffee": 44,
"pizza": 23
},
"date": "Dec 10, 2016",
"__v": 0
}
Here's what I have so far:
Poll Model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const pollData = new Schema({
title: String,
description: String,
labelOptions: {},
date: String
})
module.exports = mongoose.model('PollData', pollData)
Using express and mongoose, here's what I have:
app.put('/polls/:id', function(req, res){
let id = req.params.id;
let labelOption = req.query.labelOption;
let query = `labelOptions.${labelOption}`
Poll.findByIdAndUpdate(
id,
{$inc: { query: 1 } },
function(err, document){
console.log(err)
console.log(document)
}
)
})
In my terminal, I see that console.log(document it receives the document I was looking for but it does not update the value at all.
Am I setting up the Model correctly? Or does Mongoose does not support template strings?
***update
This is snippet of how I am creating documents
let labelOptions = {}; <=== creating object literal to hold as placeholder
const title = req.body.title;
const description = req.body.description;
req.body.labelOptions.split(/,\s*/).map( prop =>{
labelOptions[prop] = 0 // set counter to default 0
})
const poll = new Poll({
title: title,
description: description,
labelOptions: labelOptions,
date: moment().format('MMM D, YYYY')
});
poll.save(function(err) {
if (err) { return next(err); }
res.json({ message : 'Poll added!'})
});
After doing some research across the internet, I found the reason why it wasnt working: You can't initialize objects with 'dynamic' keys.
Source: Mongoose update on a string variable not working?
By knowing that, it was just a simple solution to initialize an literal object as so:
let id = req.params.id;
let labelOption = req.query.labelOption;
let query = "labelOptions." + labelOption
let obj = {
[query] : 1
}
Poll.findByIdAndUpdate(
id,
{$inc: obj },
function(err, document){
console.log(err)
console.log(document)
}
)

Resources