Deleting an element from an Array, that is inside an Object - javascript

In my To-Do app, when a logged-in User completes a task, I would like to clear it from the MongoDB database.
Here is the code for my Schema.
const user = new mongoose.Schema({
username : String,
password : String,
task : [{
text : String,
day : String,
reminder : Boolean,
]}
})
For example, if Daryl completed text : "Gym" & day : "Feb 4th 5.30pm", I would like to only remove task[0] from Daryl's task Array.
Here is my attempt at doing so using Mongoose,
app.delete("/tasks", (req,res) => {
User.findOne( {_id : req.user.id}).then((target) => {
target.task.remove({text : req.body.text, day : req.body.day})
})
})
User.findOne({_id : req.user.id}) to only target the person that logged in
Once targeted, access task array using .task
and use .remove along with filters, to remove that entry from the array
I have console.logged() all the variables and it tallies with the data fields, however the entry is not being removed. What am I doing wrong?

I managed to solve my problem, hopefully this helps someone else
app.delete("/tasks", (req, res) => {
User.findByIdAndUpdate(req.user.id, {$pull: {"task": {text: req.body.text}}}, {safe: true, upsert: true},
function (err, node) {
// console.log here for debugging, if you want
})
})
This successfully erases items based on
req.user.id
"task" : {//whatever your stricter conditions are}
I still don't understand why my earlier attempts failed, but at least this one works.

Related

Update database entry using mongoose

Hello i am using mongoose.
I have built this query that finds my desired project :
const projects = await ClientManagers.findOne({'project.contactPerson.work_email' : 'testing#email.com'} , { 'project.$.companyName': 1 });
this returns an object from my database like this :
{
'projectName' : 'x',
'companyName' : 'x bv'
}
How can i update the company name to be 'Y bv' instead of 'x bv'.
Assuming this is your document structure,
{
"_id" : ObjectId("5f2ae5a4b1549ac0460920dd"),
"projectName" : "A",
"project" : [
{
"companyName" : "T1",
"contactPerson" : {
"work_email" : "t1#gmail.com"
}
},
{
"companyName" : "T2",
"contactPerson" : {
"work_email" : "t2#gmail.com"
}
}
]
}
Single Update updateOne()
If you know email will be unique and want to update single document then use updateOne().
first is query part to find condition, email t1#gmail.com
second is set/update part, here $ is for array because project is an array, update companyName to T1 Company
await ClientManagers.updateOne(
{ 'project.contactPerson.work_email': 't1#gmail.com' },
{
$set: { "project.$.companyName": "T1 Companmy" }
}
)
Multiple Update updateMany()
If email is not unique and want to update everywhere then use updateMany(), it will update every matching documents.
await ClientManagers.updateMany(
{ 'project.contactPerson.work_email': 't1#gmail.com' },
{
$set: { "project.$.companyName": "T1 Company" }
}
)
Not suggesting update() method to use, because its deprecated in mongoose and will give Deprecation Warnings
, this function is replaced with updateOne(), updateMany() and replaceOne() methods.
Good start. Mongo has better documentation with examples. I suggest you to refer that also.
use update
db.collection.update({companyName:'x bv'}, {"$set":{"companyName":y}})
Mongo is case sensitive. So name should match exactly.
update updates one document. To update multiple, use updateMany or multi:true option with update or findOneAndMondify for one update for find and update case.

I can't get the $set operator to work on a specific field

I am writing a database backend for our game. I have been wrestling for the past 3 days with this issue. No matter what I try, I cannot get the $set operator to work on one field. Just one.
I have a GlobalLeaderboard collection, with each document containing this structure:
{
"_id" : { "$oid" : "5e7d445f5010bb548850d2ee" },
"PlayerName" : "Regen_erate",
"Rating" : 38.24,
"TotalMapsPlayed" : 372,
"UserId" : "P526993347"
}
The Node.js code that I am running to edit the database is as follows:
rating = await getRating(Plays.find({"UserId": newPlayData.UserId}).sort({"Rating": -1}));
console.log(rating);
Global.findOneAndUpdate({"UserId": newPlayData.UserId},
{
$inc: {"TotalMapsPlayed": 1},
$set: {"PlayerName": newPlayData.PlayerName},
$set: {"Rating": rating.toFixed(2)},
$set: {"UserId": newPlayData.UserId}
},
{
upsert: true,
bypassDocumentValidation: true,
ignoreUndefined: true
}).catch(err => {
console.log("ERR: " + err);
res.status(500).send("Whoops! Something went horribly wrong! Here's some info: " + err);
});
Even if I stick a random number (double) into the $set operation it still won't update. This seems to be happening for no reason at all...
I am able to run $set on all other fields except the Rating field. Out of curiosity, I tried to use $inc on the field in question, and, surprisingly, I was able to get it to work. What is going on?
The second argument to findOneAndUpdate is an object. An object can only have 1 instance of a specific field name, when you specify the same field multiple times, the last one is the value that remains. So your update document:
{
$inc: {"TotalMapsPlayed": 1},
$set: {"PlayerName": newPlayData.PlayerName},
$set: {"Rating": rating.toFixed(2)},
$set: {"UserId": newPlayData.UserId}
}
Is equivalent to
{
$inc: {"TotalMapsPlayed": 1},
$set: {"UserId": newPlayData.UserId}
}
To set multiple fields in the same update, list all of the fields inside a single $set like:
{
$inc: {"TotalMapsPlayed": 1},
$set: {"PlayerName": newPlayData.PlayerName,
"Rating": rating.toFixed(2),
"UserId": newPlayData.UserId}
}

Mongoose cast to ObjectID failed for value... but why

I know what the problem is, but can't figure out why it is happening. I have a simple recipe app using express and mongoose. User passes in recipe info via form and is saved to database via mongoose methods. This part seems to work perfectly and when I console.log using test data, I see that the following data is saved:
{
ingredients: [ 'peanut butter', 'jelly', 'bread' ],
_id: 5e47d564f775ce247052d01c,
name: 'pb jelly sammich',
author: 'rob',
oneLiner: 'classic pb jelly sammich',
image: 'picofpbsammich here',
method: 'add all the ingredients together and boom! pb jelly sammich.',
__v: 0
}
(This is also what shows when I check mongo db using db.recipes.find() and also what displays when I pass in the object to my ejs show template.
However, when I access my show route via get request, I get a long error message using the above test data. Here is they key part of the error message:
'Cast to ObjectId failed for value "picofpbsammich here" at path "_id" for model "Recipes"',
I understand what the problem is, but baffled as to why it is happening. Here is my show route:
app.get("/recipes/:id", function (req, res) {
console.log(req.params.id)
Recipe.findById(req.params.id, function (err, foundRecipe) {
if (err) {
console.log(err);
} else {
res.render("show", { recipe: foundRecipe });
}
})
})
console logging the req.params.id as shown above, prints the following:
5e47d564f775ce247052d01c
picofpbsammich here
The first line is the correct ID, the second is obviously not and the cause of the problem, but I have no idea where that could be coming from :S Why would req.params.id be pulling the VALUE of a property that is named something completely different?
I'm new to mongoose so it's probably something silly I'm doing and any explanations appreciated.
Here is the model:
var mongoose = require("mongoose");
let recipeSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
author: String,
oneLiner: String,
ingredients: [String],
image: String,
method: String
})
module.exports = mongoose.model("Recipes", recipeSchema)
You posted the following code:
app.get("/recipes/:id", function (req, res) {
console.log(req.params.id)
Recipe.findById(req.params.id, function (err, foundRecipe) {
if (err) {
console.log(err);
} else {
res.render("show", { recipe: foundRecipe });
}
})
})
And you mention that in the console.log you receive:
5e47d564f775ce247052d01c
picofpbsammich here
Followed by the exception being logged:
'Cast to ObjectId failed for value "picofpbsammich here" at path "_id"
for model "Recipes"',
Makes me logically assume that you are making two requests, one of which the id is not valid, being:
picofpbsammich here
Mongoose is not able to cast this value to an ObjectId, hence you get the exception, which makes sense imo.

Mongoose not returning, but mongo shell is

I'm using mongoose on my node app, and I want to get a seller by its email:
getSellerByEmail : function(email,next){
var Seller = mongoose.model('Seller');
console.log(inspect(email));
Seller.findOne({'email' : new RegExp(email, 'i')}, function(seller){
next(seller);
});
}
When I try to login, mongoose does not return the new user. But when I try to create another user with the same email, the server executes this function correctly and it returns the new user.
Also tried with {'email' : email} and It returns null, but when I do this query on mongo shell, it returns correctly.
db.sellers.findOne({email : 'email#email.email'});
{
"_id" : ObjectId("54b94759b042bdbf19cb7b97"),
"name" : "Nome da Empresa",
"cnpj" : "123123123",
"email" : "email#email.email",
"password" : "$2a$08$6UvW8Bux3CwUMok8ac12Sehbd.xCHnVUI51ZwhtGKBjkSa6/MrqUu",
"__v" : 0
}
I'm new to mongodb + mongoose, so I know it's a dumb question, but I just can't realize what is wrong... I've also created a findSellerById() function, and it works perfectly.
EDIT 1:
Using Mongoose debug, here's what it's printed:
Mongoose: sellers.findOne({ email: 'email#email.email' }) { fields: undefined }
Mongoose: sellers.findOne({}) { fields: undefined }
As you can see, also tried with no parameters, no success...
I had the same problem, maybe you could try this:
Seller.find({email: seller.email}, function(err, seller){
console.log(seller);
});
This solved mine, hope it will solve yours too !
The callback function passed into findOne takes two parameters (error and doc), so you're treating seller as the error parameter instead of the doc parameter.
So your function should look like this instead:
getSellerByEmail : function(email,next){
var Seller = mongoose.model('Seller');
console.log(inspect(email));
Seller.findOne({'email' : new RegExp(email, 'i')}, function(err, seller){
next(seller);
});
}

Add a field to existing MongoDB document (with Mongoose in Node.js)

I have this existing document in a collection Article in MongoDB database:
[ { site: 'www.atlantico.fr',
date: '2014-05-27T11:10:19.000Z',
link: 'http://www.atlantico.fr/example.html',
_id: 538473817eb00f082f4803fc,
__v: 0} ]
I want to add a new field day with value 'example' to this document, using Mongoose in Node.js. So I do:
Article.update(
{ link: 'http://www.atlantico.fr/example.html'},
{ $set : {day : 'example'} },
function(err){
});
But it does not work because when I query the document after that, no new field day appears...
I must have made a mistake when using update or $set in Mongoose, but I cannot find exactly my mistake.
What am I missing? Thanks!
try
Article.update(
{link: 'http://www.atlantico.fr/example.html'},
{day : 'example' },
{multi:true},
function(err, numberAffected){
});
and don't forget to add day to schema.
await Users.updateOne( {link: 'http://www.atlantico.fr/example.html'},{ $set: { day : 'example'} }, { multi: true });
update is deprecated
use await for db operation
if you want to add new filed in collection ,first check it is added in Model or not
(if you don't wan't use that filed as mandatory make is as "required: false")
Article.findByIdAndUpdate(id, { $set: { day: 'example' }}, { new: true }, function (err, article) {
if (err) return handleError(err);
res.send(article);
});
I prefer this way because it's contains a callback function.
reference and more info: http://mongoosejs.com/docs/documents.html

Categories

Resources