working with a full MEAN stack.
trying to write data to a "notes" array in my mongodb document id #1.
mongo document:
> db.contacts.find().pretty()
{
"_id" : ObjectId("5a294af85e96746421bf35f1"),
"id" : 1,
"type" : "dealer",
"name" : "ken yoder",
"company" : "kens sales",
"phone" : "817-403-9767",
"notes" : [
{
"date" : "Thu Dec 07 2017 08:15:37 GMT-0600 (CST)",
"by" : "#me",
"note" : "this is a note"
},
{
"date" : "Thu Dec 07 2017 08:16:31 GMT-0600 (CST)",
"by" : "#donny",
"note" : "bla bla bla mumford and sons"
},
{
"date" : "Thu Dec 07 2017 08:34:03 GMT-0600 (CST)",
"by" : "#ken",
"note" : "test with another note"
},
{
"date" : "Thu Dec 07 2017 08:34:29 GMT-0600 (CST)",
"by" : "#ken",
"note" : "test with another notey note note"
}
],
"setNotes" : {
"date" : "Thu Dec 07 2017 10:52:09 GMT-0600 (CST)",
"by" : "#kale",
"note" : "hhsdihufiudhsiuhdshuifds"
}
}
express code:
app.get('/newNote/:noteFor/:noteCount/:noteBy/:note/', function (req, res) {
var setNotes = "notes."+req.params.noteCount;
db.collection('contacts').update({ id:req.params.noteFor }, { $set: { setNotes : {date: Date(), by: req.params.noteBy, note: req.params.note} }}, function(err, res) {
if (err) throw err;
console.log("notefor: "+req.params.noteFor+" noteCount: "+setNotes+" noteBy: "+req.params.noteBy+" note: "+req.params.note);
console.log(res.result.nModified + " for " + req.params.noteFor + " updated");
});
});
if i run this code as it sits, i get nothing, no insert, no errors.
- if i change the update id from "req.params.id" to "1", i get an insert but...
- instead of using my "setNotes" variable (which outputs "notes.4") for the $set identifier, it created a new object called "setNotes".
API URL: /newNote/1/4/#kale/this is a note test
This will just add a new document everytime to notes array:
db.collection('contacts').update({ id:req.params.noteFor }, {
$push: {
notes : {date: Date(), by: req.params.noteBy, note: req.params.note}
}
}, function(err, res) {
//code
}
first read express api basics, http://expressjs.com/en/4x/api.html. from question there is noting in req.params.id , instead of id req.params contain four keys (noteFor, noteCount, noteBy and note ). also you override res varible by result of query notice function(err, res) {.........
db.collection('contacts').update(
{ id:req.params.id },
{ $set:
{ setNotes : {date: Date(), by: req.params.noteBy, note: req.params.note} }
},
{
// if noting found then stop create new document with values of $set
upsert:false
// result should be updated document
new:true
},
function(err, result) {
console.log(err, result)
})
Related
filesArray is the array of objects means contain all files upload datas like path, filename etc. So I am just fetching the path and filename and pushing it into another array called Bigpaths2. So while I am pushing Bigpaths2 into the Addtasks array's array Bigpaths4clients it get pushed successfully but by creating another array inside Bigpaths4clients and then get pushed in form of objects.
But I don't want that. I want to prevent that array creation. I just want all the paths object inside Bigpaths2 should directly be pushed inside Bigpaths4clients array creating single objects. I have attached an image as well in last to conclude which i dont want. Check json format as well thanks!
var Bigpaths2 = [], paths;
filesArray.forEach(element => {
paths = {
"path": element.path,
"name": element.filename
};
Bigpaths2.push(paths);
})
User.findOneAndUpdate(
{ 'Addtasks.commonID':cid },
{ $push: { 'Addtasks.$.Bigpaths4Clients': Bigpaths2 } },
function (error, WriterData) {
if (error) {
console.log(error);
}
else
{
console.log("success");
}
}
)
User schema:
[
{
"assignee" : "Charlotte Miles",
"displayLock" : "none",
"displayDelete" : "inline",
"commonID" : "x0yosfn1uz",
"status" : "Approved by Admin",
"Date" : "Fri Sep 04 2020 15:36:11 GMT+0530 (India Standard Time)",
"exampleRadios" : "option1",
"otherdetails" : "haha great!",
"website" : "asad.com",
"keywords" : "article importance, article generation, article quality",
"words" : 12345,
"topic" : "How article is generated?",
"_id" : ObjectId("5f5211b29dc68d04244a6774"),
"Bigpaths4Clients" : [
[
{
"name" : "api-ms-win-core-errorhandling-l1-1-0.dll",
"path" : "public\\files\\api-ms-win-core-errorhandling-l1-1-0.dll"
}
]
],
"Bigpaths" : [
{
"path" : "public\\files\\api-ms-win-core-errorhandling-l1-1-0.dll",
"name" : "api-ms-win-core-errorhandling-l1-1-0.dll"
}
]
}
]
User.findOneAndUpdate(
{ 'Addtasks.commonID':cid },
{ $push: { 'Addtasks.$.Bigpaths4Clients': { $each: Bigpaths2 } } },
function (error, WriterData) {
if (error) {
console.log(error);
}
else
{
console.log("success");
}
}
)
$each operator is used to append multiple values to the array field.
In your case, MongoDB considering the whole Bigpaths2 array as a single element to append to Bigpaths4Clients array
here's the official dock link https://docs.mongodb.com/manual/reference/operator/update/push/#append-multiple-values-to-an-array
Although its printing the 'success' in console but i am unable to see the changes after clicking on post update.
User.update( { email:req.user.email },
{ $set: {
"Addtasks.$[].topic": req.body.topic,
"Addtasks.$[].words": req.body.words,
"Addtasks.$[].keywords": req.body.keywords,
"Addtasks.$[].website": req.body.website,
"Addtasks.$[].otherdetails": req.body.otherdetails,
"Addtasks.$[].exampleRadios": req.body.exampleRadios
} },function (error, success) {
if (error) {
console.log(error);
} else {
res.redirect('/status');
console.log('success');
}
} )
My json array file:
[
{
"Date" : "Mon Aug 03 2020 03:30:17 GMT+0530 (India Standard Time)",
"exampleRadios" : "option1",
"otherdetails" : "haha great!",
"website" : "nmbn.com",
"keywords" : "anxiety disorders for children, anxiety disorders for adults",
"words" : 456,
"topic" : "How to fight anxiety",
"_id" : ObjectId("5f273771ddff850558b1e049")
}
]
Did you checked the db if it's updated? Because if you using native mongodriver, update will not return document itself, you have to use findOneAndUpdate. Second thing, findOneAndUpdate will not return updated document, but old one (dunno why they configured it like this), you have to use options = { returnOriginal: false } (default is true).
I have written an update query in MongoDB/NodeJS that deletes objects from an array of a document, based on the parameters I define. After I pull these objects, I would like to to increment another variable in the document based on how many documents were modified by the update query.
Here is an example of one of my events documents:
{
"_id" : ObjectId("575ed7fca7b89bb4027dded9"),
"dateCreated" : "6/13/2016",
"latitude" : "56.294786195890076",
"longitude" : "-43.59161567687988",
"instructorName" : "Test User",
"instructorEmail" : "test#user.com",
"instructorRating" : 5,
"eventName" : "We gon exercise",
"eventDescription" : "We gon exercise",
"spacesAvailable" : 15,
"streetAddress" : "123 wer",
"city" : "rty",
"state" : "NY",
"zip" : "12332",
"date" : "06/21/2016",
"startTime" : "12:00",
"endTime" : "02:10",
"tags" : [
"Cardio",
"Crossfit"
],
"price" : 5,
"attendies" : [
{
"_id" : ObjectId("5759cfcdb71d80fb2d1203ef"),
"name" : "Buddy Loester",
"email" : "Bud18#gmail.com",
"timeStamp" : 1467048318510,
"payed" : true
},
{
"_id" : ObjectId("574f257b05086e2c7f7940ca"),
"name" : "Trainer Trainer",
"email" : "trainer#user.com",
"timeStamp" : 1467055627894,
"payed" : true
}
],
"unpayed" : 0
}
Here is my code to give a better visualization:
var eventCollection = req.db.get('events');
// get current time since epoch in milliseconds
var milliSinceEpoch = new Date().getTime();
eventCollection.update(
{"attendies.payed" : {$eq : false}},
{
$pull:
{
"attendies" : {"timeStamp": {$lt: milliSinceEpoch /*- 600000*/}}
},
$inc:
{
spacesAvailable: numberAffected
}
},
{
multi: true
}, function(err, numberAffected) {
console.log(numberAffected);
return res.end();
}
);
If I specify 'numberAffected' in the query portion to '1', then it works as expected and increments by 1. However, I would like to increment by the number affected.
I know this code will not work with 'numberAffected' in the query. Using 'numberAffected' in the callback actually does return the number of documents modified by my query.
Does there exist a way in MongoDB to do what I am trying to do?
I have solved my problem by rewriting the query. It is as follows:
var ObjectID = require("mongodb").ObjectID;
var eventCollection = req.db.get('events');
var milliSinceEpoch = new Date().getTime();
// find and return all the documents in the events DB where there is a user who has not payed for an event
// they RSVP'd for
eventCollection.find({"attendies.payed" : {$eq : false}}, function(err, documentsWithUnpayedUsers) {
// if error finding, print it and return
if(err) {
console.log(err);
return res.sendStatus(400, "Error cancelling");
}
// if everyone has payed for all RSVP'd events
if(!documentsWithUnpayedUsers) return res.sendStatus(404, "Everyone has payed!");
// loop through every document which has people who have not yet payed for RSVP'd events
for(var i = 0; i < documentsWithUnpayedUsers.length; i++) {
// for each of these documents:
eventCollection.update(
{_id: ObjectID(documentsWithUnpayedUsers[i]._id)},
{
// remove the user from the attendie list if they have not payed,
// and it has been 10 minutes since they RSVP'd
$pull:
{
"attendies" : {"timeStamp": {$lt: milliSinceEpoch - 600000}, "payed" : {$eq : false}}
},
// then modify the number of spaces available for the event by the number of people who were
// removed from the attendie list
// then modify the amount of people who have not payed for the event yet (will now be 0)
$inc:
{
spacesAvailable: documentsWithUnpayedUsers[i].unpayed,
unpayed: -documentsWithUnpayedUsers[i].unpayed
}
}, function(err) {
// error checking for the update query
if(err){
console.log(err);
return res.sendStatus(400, "There was an error removing an attendie fom the event: "
+ documentsWithUnpayedUsers[i].eventName);
}
}
); // end of update query
} // end of for loop
return res.end();
}
); // end of find()
}); // end of checkPayed
This is my entry in database in mongodb which is of type object in schema
"_id" : ObjectId("5539bed4b417d75d1fee5df7"),
"favMovies" : {
"alternate_ids" : {
"imdb" : "2820852"
},
"studio" : "Universal Pictures",
"abridged_directors" : [
{
"name" : "James Wan"
}
],
"abridged_cast" : [
{
"characters" : [
"Dominic Toretto"
],
"id" : "162652472",
"name" : "Vin Diesel"
},
{
"characters" : [
"Brian O'Conner"
],
"id" : "162654234",
"name" : "Paul Walker"
},
{
"characters" : [
"Louie Tran"
],
"id" : "162684066",
"name" : "Tony Jaa"
},
{
"characters" : [
"Deckard Shaw"
],
"id" : "162653720",
"name" : "Jason Statham"
},
{
"characters" : [
"Luke Hobbs"
],
"id" : "770893686",
"name" : "Dwayne \"The Rock\" Johnson"
}
],
"synopsis" : "Continuing the global exploits in the unstoppable franchise built on speed, Vin Diesel, Paul Walker and Dwayne Johnson lead the returning cast of Fast & Furious 7. James Wan directs this chapter of the hugely successful series that also welcomes back favorites Michelle Rodriguez, Jordana Brewster, Tyrese Gibson, Chris \"Ludacris\" Bridges, Elsa Pataky and Lucas Black. They are joined by international action stars new to the franchise including Jason Statham, Djimon Hounsou, Tony Jaa, Ronda Rousey and Kurt Russell.",
"ratings" : {
"audience_score" : 88,
"audience_rating" : "Upright",
"critics_score" : 82,
"critics_rating" : "Certified Fresh"
},
"release_dates" : {
"theater" : "2015-04-03"
},
"critics_consensus" : "",
"runtime" : 140,
"mpaa_rating" : "PG-13",
"genres" : [
"Mystery & Suspense",
"Action & Adventure"
],
"year" : 2015,
"title" : "Furious 7",
"id" : 771354922
},
"username" : "punk",
"__v" : 0
}
In my Node JS code I use the following query
app.delete('/favMovies/:user/:movid',function(req, res){
var user = req.params.user;
var mid = req.params.movid;
console.log(mid);
console.log(user);
MovModel.find({username:user,'favMovies.id':mid}, function (err, doc) {
doc.remove();
MovModel.find({username: user},function (err, data) {
res.json(data);
});
});
});
In the above snippet mid is movie id. For the above entry in database mov
"id" : 771354922
and user is username but I am getting following error for my query which is working fine in mongo client.
/Users/pankajtripathi/Documents/ECLIPSE-FILES/MyProject/server.js:132
doc.remove();
^
TypeError: Cannot read property 'remove' of null
at /Users/pankajtripathi/Documents/ECLIPSE-FILES/MyProject/server.js:132:5
at /Users/pankajtripathi/Documents/ECLIPSE-FILES/MyProject/node_modules/mongoose/lib/query.js:1169:16
at /Users/pankajtripathi/Documents/ECLIPSE-FILES/MyProject/node_modules/mongoose/node_modules/kareem/index.js:103:16
at process._tickCallback (node.js:355:11)
You should use findOneAndRemove()
MovModel.findOneAndRemove({username:user,'favMovies.id':mid}, function (err, doc) {
if (err) console.log(err);
res.json(doc);
}
Finds a matching document, removes it, passing the found document (if
any) to the callback. Executes immediately if callback is passed.
I changed the query and its working fine now.
MovModel.findOneAndRemove({username:user,_id:mid}, function (err, doc) {
console.log(doc);
MovModel.find({username: user},function (err, data) {
res.json(data);
});
});
Pretty new to mongo and mongoose.
I have
var mongoose = require('mongoose'),
errorHandler = require('./errors'),
ClientSummary = mongoose.model('ClientSummary');
exports.list = function(req, res) { ClientSummary.find().sort('-LastName').exec(function(err, clients) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
console.log(clients);
res.jsonp(clients);
}
});
};
this returns double results for each client
I copied this from the console
[ { _id: '_?\u0007Z?WM???3\u0016?\u0017',
ArchivedDate: Sun Dec 31 0 18:00:00 GMT-0600 (Central Standard Time),
ArchiveDate: Sat Nov 08 2014 17:18:55 GMT-0600 (Central Standard Time),
Archived: false,
Phone: null,
EmailAddress: 'test#test.com',
LastName: 'test',
FirstName: 'test' },
{ _id: '??\u0002otsF???\u000fF\u0010\u0019\n',
ArchivedDate: Sun Dec 31 0 18:00:00 GMT-0600 (Central Standard Time),
ArchiveDate: Sat Nov 08 2014 17:18:55 GMT-0600 (Central Standard Time),
Archived: false,
Phone: null,
EmailAddress: 'test#test.com',
LastName: 'test',
FirstName: 'test' } ]
I get this from a query
db.clients.find()
{ "_id" : BinData(4,"U/UnaPQyRxqtc1iPJP7Lyw=="), "Contact" : { "FirstName" : "test", "LastName" : "test", "EmailAddress" : "test#test.com", "Phone" : null, "PhoneSecondary" : null }, "Address" : null, "Source" : null, "SourceNotes" : "asdf", "Archived" : false, "ArchivedDate" : ISODate("0001-01-01T00:00:00Z"), "StartDate" : ISODate("0001-01-01T00:00:00Z") }
any thoughts would be greatly appreciated
Thanks,
Raif
I do not see why you are saying that you have duplicate results in the first query. The _ids are different, so, it looks like there are two different objects.
Further, I also think that the second query that you have refers to a different collection; i.e. clients, while the first query refers to the collection clientsummary.
For example, use the mongo shell, connect to the db *, and try the following two:
> show collections
If I am right, you have both clients and clientsummary as collections in your db. Then, also try
> db.clientsummary.count()
This should return 2.
Note, that it might be the case that you have clientSummary instead of clientsummary as collection in your db, or even clientsummarys/clientSummarys or clientsummaries/clientSummaries as mongo/mongoose will use the plural for the collection and an s is usually attached in the end of the word referring to the collection. Just use the right name.
(*) You can connect to the db mydb (where the collections you are referring to can be found) using the command:
$ mongo --shell localhost/mydb
(Assuming you have mydb on localhost.)