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

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

Related

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

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.

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}
}

Sails.js populate filter

I am trying to get all of my posts' comments which comments count is greater than 0. I am tying to add the where in find and populate, but none of it worked.
Post model:
module.exports = {
attributes: {
user: {
model: 'user'
},
comments: {
collection: 'comment',
via: 'post'
}
};
PostController:
Post
.find({comments: {'>': 0}, user: me})
.populate('comments')
.exec(function(err, comments){
res.json(comments);
});
In current Sails/Waterline relations implementation you can't filter by one-to-many related fields. You need to filter the result after find is completed.

How bind search values in mongodb with mongoose

I have the following code in my /search/:query route:
var param = {
query: req.query['query']
}
MyModel.find({
"$or": [
{ 'name': req.param.query },
{ 'age': req.param.query },
{ 'event': req.param.query },
]
}, function (err, results) {
if (err) {
console.log(err)
}
else {
res.render('index', {
data: results
});
}
}
);
And is good, i can search for pretty much every data that i want, but only individually. What if i want search name + age, can i? Example: 'Leo 22'.
There is any way that mongoose help me with this?
UPDATE:
My problem is:
I have tables lists it titles, this title is the concatenation of 'eventName' and 'eventDate'.
Real examples of this fields:
'Special Event - 20/12/2015'
'Classic Event - 12/03/2015'
'Hot Summer Event - 05/07/2005'
Every week will be create 4 events. In some point, a user will search for an old event, and i believe that the user will search in this format:'EVENT NAME - EVENT DATE'..
So i need a way to bind this values in my controllers.
I'm no familiar with mongoose but in order to do that, you must have a way to bind your query param to the attribute you want to search. Otherwise, they wouldn't know Leo is name and 22 is age.
Ur path would be like search?name=:name&age=:age&event=:event and in your code, you will have to process like if the param is not null, add and condition to it.
It seems you are using only one parameter (req.param.query) to filter all attributes. That's not mongoose related: you could create distinct parameters for each attribute and pass them along the query string.
For instance:
"$or": [
{ 'name': req.param.name },
{ 'age': req.param.age },
{ 'event': req.param.event },
]
And your HTTP request will be like this:
http://youraddress/expressRoute?name=Leo&age=22

Set a value with mongoose in NodeJS

I have a NodeJS application that communicates with an Angular app. This is a simplified version, but I'll try to explain my problem:
I will get a value from the socket connection, for example:
{
Id : "1",
Checked : true,
TeamName : "Team1"
}
I want to update the mongoDb with mongoose so that every person with the TeamName : "Team1" gets the value Checked : true.
I have done something like this:
relayModel.find({TeamName : 'Team1'},
{'$set' :{Checked: true}},function(err,docs){
if(err){
console.log("Could not save value for relay runner: ", err);
}
else{
console.log("The runners updated: ",docs)
}
But I get the error:
Could not save value for relay runner:
{ [MongoError: Can't canonicalize query:
BadValue Unsupported projection option:
$set: { Checked: true }] name: 'MongoError' }
This really is well documented. Will go away for sure, but just to explain for you:
relayModel.update(
{ "TeamName": "Team1" },
{ "$set": { "Checked": true } },
{ "multi": true },
function(err,numAffected) {
if (err) throw err;
console.log( "updated n docs: %s", numAffected );
}
);
So the .update() with a "multi" option affects more than one document, and without it it just affects the first document matched. The returned values in the callback are the standard err and the "number of documents affected".
Therefore basically speaking:
You actually need and operator that "updates" in order to affect and update.
You set "multi" for more than one document and you get only the number returned as well as using the $set operator to just affect the field that you want to change.

Categories

Resources