Search an array of objects to match objectId from mongodb - javascript

I'm trying to search an array of objects by a key that contains nested object id for populating.
My object
{
service: 'user',
isModerator: true,
isAdmin: true,
carts: [
{
_id: 5e1344dcd4c94a1554ae0191,
qty: 1,
product: 5e09e4e0fcda6f268cefef3f,
user: 5e0dda6d6853702038da60f0,
expireAt: 2020-01-06T14:31:56.708Z,
__v: 0
},
{
_id: 5e13455306a54b31fc71b371,
qty: 1,
product: 5e09e507fcda6f268cefef40,// object ID
user: 5e0dda6d6853702038da60f0,
expireAt: 2020-01-06T14:33:55.573Z,
__v: 0
},
],
I want to match if carts array, contains cart with a product that user is adding, to not add it the second time but instead increment qty of the existing one.
My code
const itemId = req.body._id;
const userId = req.user._id;
const { qty } = req.body;
try {
const producto = await Product.findById(itemId);
const user = await User.findById(userId).populate({
path: 'carts',
});
const result = user.carts.find((o) => {
console.log(typeof o.product) // returns object
console.log(typeof producto._id); // returns object
return o.product === producto._id
});
console.log(result); // returns undefined
if (result !== undefined) {
const foundCart = await Cart.findById(result._id);
foundCart.qty += qty;
await foundCart.save();
return res.json({ message: 1 });
}
const newCart = new Cart({
qty,
product: producto,
user,
});
const cart = await newCart.save();
user.carts.push(cart);
await user.save();
return res.json({ message: 1 });
} catch (error) {
return console.log(error);
}

I think the problem is this line
return o.product === producto._id
Can you change it like this and try?
return o.product.toString() === producto._id.toString()

Related

How to use updateOne in Mongodb using NodeJS

Below is my code to update a website field in Mongodb using NodeJS, instead of updating however it adds a new field to my database.
let { ObjectId } = require('mongodb');
async get(id) {
if (!id) throw 'You must provide an id to search for';
const restaurantsCollection = await restaurants();
const res = await restaurantsCollection.findOne({ _id: id });
if (res === null) throw 'No dog with that id';
res._id = res._id.toString().replace(/ObjectId\("(.*)"\)/, "$1")
return res;
}
async rename(id, newWebsite) {
if (!id) throw 'You must provide an id to search for';
if (!newWebsite) throw 'You must provide a name for the restaurant';
let newid = ObjectId(id);
const restaurantsCollection = await restaurants();
const updatedInfo = await restaurantsCollection.updateOne(
{ _id: newid },
{ $set: {website:newWebsite} }
);
if (updatedInfo.modifiedCount === 0) {
throw 'could not update restaurant successfully';
}
return await this.get(newid);
}
};
Below is the output I get:
{
_id: new ObjectId("6157825a4dcae5beb8f759bf"),
name: 'Hey',
location: 'New York City, New York',
phoneNumber: '123-456-7890',
website: 'http://www.hey.com',
priceRange: '$$$$',
cuisines: [ 'Cuban', 'Italian' ],
overallRating: 3,
serviceOptions: { dineIn: true, takeOut: true, delivery: false },
newWebsite: 'http://www.hi.com'
}
Instead of the website being replaced from hey.com to hi.com it just adds a new field, what am I doing wrong?
Instead of using { $set: {website:newWebsite} }
It should just be {website:newWebsite}

Want to update MongoDB with data that does not include objects that include the paid: true key/value

Good Evening,
I am using the MERN stack to create an application. I am using the Stripe API to gather invoices and save some information about the invoice in MongoDB. Right now I have a function that updates my DB with any object that does not exist and I have a delete function that deletes any documents in my DB that have the paid: true. when an invoice is paid Stripe marks it paid, when its paid I want to delete it from my DB. What happens now is that I delete it and then update function runs and just puts it right back.
The data in my DB and from stripe are an array of objects:
DB Sample:
[
{
Id: String,
created: Number,
customer_email: String,
customer_name: String,
due_date: Number,
hosted_invoice_url: String,
paid: Boolean
}
]
Codebase functions:
// Update and store function
async function saveInvoice(stripeInvoice) {
const condition = {id: stripeInvoice.id};
const query = {
id: stripeInvoice.id,
created: stripeInvoice.created,
customer_email: stripeInvoice.customer_email,
customer_name: stripeInvoice.customer_name,
due_date: stripeInvoice.due_date,
hosted_invoice_url: stripeInvoice.hosted_invoice_url,
paid: stripeInvoice.paid,
};
const options = { upsert: true };
const update = await InvoiceModel.updateMany(condition, query, options).catch((e) => {console.log(e)});
if(update.nModified > 0 ) {
console.log('Number of Invoices added or updated to DB:', update.nModified)
}
}
// Find common ID
function findCommoneID(stripeInvoice, DBInvoices) {
var isSame = true;
if(DBInvoices.length <= 0 || stripeInvoice.length <= 0) {
console.log('An Error has occured with Database or Stripe Data')
return isSame = false;
} else {
stripeInvoice.forEach((StripeElement) => {
DBInvoices.forEach((DBElement) => {
if(StripeElement.id !== DBElement.id) {
saveInvoice(StripeElement, DBElement);
isSame = false;
}
})
});
}
console.log('IDS match')
return isSame;
}
// Delete Function
async function deletePaidInvoicesFromDB(dbInvoices) {
for(let i = 0; i < dbInvoices.length; i++) {
if(dbInvoices[i].paid === true ) {
console.log(dbInvoices[i].id);
const deletedInvoices = await InvoiceModel.deleteMany({paid: true});
console.log(deletedInvoices.deletedCount)
break;
}
}
}
The save function takes in the data gathered from the findCommonId() function and if the id doesn't exist it adds the stripe object to the DB.
// Save Function
async function saveInvoice(stripeInvoice) {
if(stripeInvoice.paid === true) {
return;
} else {
const condition = {id: stripeInvoice.id};
const query = {
id: stripeInvoice.id,
amount_due: stripeInvoice.amount_due,
created: stripeInvoice.created,
customer_email: stripeInvoice.customer_email,
customer_name: stripeInvoice.customer_name,
due_date: stripeInvoice.due_date,
hosted_invoice_url: stripeInvoice.hosted_invoice_url,
paid: stripeInvoice.paid,
};
const options = { upsert: true };
const update = await InvoiceModel.updateMany(condition, query, options).catch((e) => {console.log(e)});
if(update.nModified > 0 ) {
console.log('Number of Invoices added or updated to DB:', update.nModified)
}
}
}
// findCommoneId
function findCommoneID(stripeInvoice, DBInvoices) {
if(DBInvoices.length <= 0 || stripeInvoice.length <= 0) {
InvoiceModel.create(stripeInvoice, () => {console.log('Invoices saved to database')});
console.log('An Error has occured with Database or Stripe Data')
stripeInvoice.forEach((StripeElement) => {
if(StripeElement.paid === true) {
return;
}
})
stripeInvoice.forEach((StripeElement) => {
DBInvoices.forEach((DBElement) => {
if(StripeElement.id !== DBElement.id) {
saveInvoice(StripeElement);
}
})
});
}
console.log('IDS match')
}

mongoose find returning empty array even their is a value on the database

I'm trying to add commodity data to my stockrecord collection and if the commodity name is already in the stockrecord collection I just want to add the quantity of the commodity quantity to my stockrecord quantity.
but even their is existing data the, find method is returning an empty array
This my code
commodity.map(async (e) => {
const data = await new Commodity({
name: e.commodityName,
units: e.units,
quantity: e.quantity,
});
data.donator = donator;
await data.save();
const stock = await StockRecord.find({
name: {
$eq: e.commodityName,
},
});
//console.log(stock);
if (stock.length === 0) {
const record = await new StockRecord({
name: e.commodityName,
units: e.units,
quantity: parseFloat(e.quantity),
});
await record.save();
console.log(record);
} else {
console.log('may sulud');
stock[0].quantity += parseFloat(e.quantity);
await stock[0].save();
}
});
This is my stockrecord model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const stockRecordSchema = new Schema({
name: {
type: String,
},
units: {
type: String,
enum: \['kg', 'pcs'\],
},
quantity: {
type: Number,
},
});
Array.map does not accept Promises
Try using for (const item of commodity) { //async magic here }

Why is this mongoose 'findOne' query always returning null?

I am trying to find a specific document with mongoose in my Cosmosdb with this query described below.
const mongoose = require('mongoose');
var ObjectID = require('mongodb').ObjectID
const keys = require('../config/keys');
const Item = mongoose.model('items');
const uploadToBlob = async (containerName, blobName, json, id) => {
console.log('id', id)
Item.findOne({ _id: id }, (foundItem) => {
console.log(foundItem)
});
console.log('here')
Item.findOneAndDelete({ name: blobName });
};
I am successfully able to find the document when querying like this below.
const scanMongo = () => {
Item.find({
_id: {
$gt: ObjectID.createFromTime(Date.now() / keys.mongoPurgeInterval)
}}, (err, foundItems) => {
if(err) {
console.log("Oops", err);
return;
}
foundItems.forEach(item => {
JSON.stringify(item)
const blobName = item.name;
json = "'"+item+"'"
const id = item._id
uploadToBlob(keys.containerName, blobName, json, id);
});
});
}
This is what the object I'm looking for looks like when pulled from the query above.
[ { _id: 5cabd5c6e16288230cba2cf6, name: 'test', value: 1, __v: 0 } ]
For kicks, here my model.
const mongoose = require('mongoose');
const { Schema } = mongoose;
const itemSchema = new Schema({
name: String,
value: Number,
});
mongoose.model('items', itemSchema);
I'm befuddled. Any help would be bawler. Thanks!!!
Yeah, the first parameter is supposed to catch the error.
Item.findOne({ _id: id }, (error, foundItem) => {
console.log(foundItem)

Update fields in object with mongoose in mongodb

I have a simple collection in mongodb.
I use mongoose.
I have users model with one field type object.
And I want change this object dynamically. But this code doesn't work, I used findByIdAndUpdate(), findById, findOne(), findOneAndUpdate().
const UsersSchema = mongoose.Schema({
likes: {}
},
{ collection: 'users' });
const Users = mongoose.model('Users', UsersSchema);
const id ="5b4c540f14f353a4b9875af4";
const thems = ['foo', 'bar'];
Users.findById(id, (err, res) => {
thems.map(item => {
if (res.like[item]) {
res.like[item] = res.like[item] + 1;
} else {
res.like[item] = 1;
}
});
res.save();
});
I believe that, for solve this problem you need to add more fields in your schema:
I created one example with this data:
const UsersSchema = new mongoose.Schema({
likes :[
{
thema:{
type: String
},
likes_amount:{
type: Number
},
_id:false
}]
});
module.exports = mongoose.model('Users', UsersSchema);
I added one user:
var newUser = new UserModel({
likes:[{
thema:'foo',
likes_amount:1
}]
});
newUser.save();
Here the code that increment the likes per thema:
const thems = ['foo', 'bar'];
const userId = "5b4d0b1a1ce6ac3153850b6a";
UserModel.findOne({_id:userId})
.then((result) => {
var userThemas = result.likes.map(item => {
return item.thema;
});
for (var i = 0; i < thems.length; i++) {
//if exists it will increment 1 like
if (userThemas.includes(thems[i])) {
UserModel.update({_id: result._id, "likes.thema" : thems[i]}, {$inc: {"likes.$.likes_amount": 1}})
.then((result) => {
console.log(result);
}).catch((err) => {
console.log(err)
});
} else {
//if doesn't exist it will create a thema with 1 like
UserModel.update({_id: result._id},
{
$addToSet: {
likes: {
$each: [{thema: thems[i], likes_amount: 1}]
}
}})
.then((result) => {
console.log(result);
}).catch((err) => {
console.log(err)
});
}
}
}).catch((err) => {
console.log(err)
});
Database result of this increment:
I hope that it can help you.

Categories

Resources