Adding to an array in MongoDB using $addToSet - javascript

I'm trying to add data to an array defined in my mongoDB called "signedUp" it is within my Timetable Schema. So far i've been able to update other fields of my schema correctly however my signedUp array always remains empty. I ensured the variable being added was not empty.
Here is my Schema
var TimetableSchema = new mongoose.Schema({
date: {
type: String,
required: true,
trim: true
},
spaces: {
type: Number,
required: true
},
classes: [ClassSchema],
signedUp: [{
type: String
}]
});
This was my latest attempt but no value is ever added to the signedUp array.
My API update request
id = {_id: req.params.id};
space = {spaces: newRemainingCapacity};
signedUp = {$addToSet:{signedUp: currentUser}};
Timetable.update(id,space,signedUp,function(err, timetable){
if(err) throw err;
console.log("updates");
res.send({timetable});
});
Thanks

You can take a look at db.collection.update() documentation. Second parameter takes update and 3rd one represents operation options while you're trying to pass your $addToSet as third param. Your operation should look like below:
id = {_id: req.params.id};
space = { $set: { spaces: newRemainingCapacity }};
signedUp = { $addToSet:{ signedUp: currentUser}};
update = { ...space, ...signedUp }
Timetable.update(id,update,function(err, timetable){
if(err) throw err;
console.log("updates");
res.send({timetable});
});

space and signedUp are together the second argument.
try this:
id = {_id: req.params.id};
space = {spaces: newRemainingCapacity};
signedUp = {$addToSet:{signedUp: currentUser}};
Timetable.update(id, {...space, ...signedUp}, function(err, timetable){
if(err) throw err;
console.log("updates");
res.send({timetable});
});

Related

Mongoose - Deleting documents is unresponsive

I'm trying to use Mongoose (MongoDB JS library) to create a basic database, but I can't figure out how to delete the documents / items, I'm not sure what the technical term for them is.
Everything seems to work fine, when I use Item.findById(result[i].id), it returns a valid id of the item, but when I use Item.findByIdAndDelete(result[i].id), the function doesn't seem to start at all.
This is a snippet the code that I have: (Sorry in advance for bad indentation)
const testSchema = new schema({
item: {
type: String,
required: true
},
detail: {
type: String,
required: true
},
quantity: {
type: String,
required: true
}
})
const Item = mongoose.model("testitems", testSchema)
Item.find()
.then((result) => {
for (i in result) {
Item.findByIdAndDelete(result[i].id), function(err, result) {
if (err) {
console.log(err)
}
else {
console.log("Deleted " + result)
}
}
}
mongoose.connection.close()
})
.catch((err) => {
console.log(err)
})
I'm not sure what I'm doing wrong, and I haven't been able to find anything on the internet.
Any help is appreciated, thanks.
_id is a special field on MongoDB documents that by default is the type ObjectId. Mongoose creates this field for you automatically. So a sample document in your testitems collection might look like:
{
_id: ObjectId("..."),
item: "xxx",
detail: "yyy",
quantity: "zzz"
}
However, you retrieve this value with id. The reason you get a value back even though the field is called _id is because Mongoose creates a virtual getter for id:
Mongoose assigns each of your schemas an id virtual getter by default which returns the document's _id field cast to a string, or in the case of ObjectIds, its hexString. If you don't want an id getter added to your schema, you may disable it by passing this option at schema construction time.
The key takeaway is that when you get this value with id it is a string, not an ObjectId. Because the types don't match, MongoDB will not delete anything.
To make sure the values and types match, you should use result[i]._id.

Mongoose .findOne Error returns the model found?

So I'm trying to access this account by using the findOne function in mongoose, and I'm trying to console.log the error, but the error is just the correct model found.. once I find the correct model I want to access one of the nested objects in the schema so I can edit the value.
I'm not sure why this is happening, below I put the code as well as the error that was logged into the console, I can provide more if needed.
let accountSchema = mongoose.Schema({
username:{
type: String,
required: true,
index: true,
unique: true,
},
password:{
type: String,
required: true,
},
money:{
type: Number,
},
inventory: { type: [{
weed: { type: Number },
coke: { type: Number },
}]},
});
mp.events.addCommand('coke', (player) => {
console.log(player.name);
Account.findOne({username: 'a'}, function(acc, err) {
if(err) return console.log(err);
console.log(acc.username);
acc.inventory[1] = acc.inventory[1] + 1;
acc.save(function(err){
if(err) return player.outputChatBox('Not logged in');
player.outputChatBox('Added 1 coke');
});
});
});
(Console) {"_id":"5b6acbbbc285477e39514cb9","username":"a","password":"$2a$10$XABqooqFRINYVdJ79.i2E.5xdpitRrfZxUBmIPAZjjaXKvvLDc2y2","money":5000,"inventory":[{"_id":"5b6acbbbc285477e39514cbb","weed":0},{"_id":"5b6acbbbc285477e39514cba","coke":0}],"__v":0}
The callback function for the .findOne method has the following signature:
function (err, obj) {
}
You are using the arguments in the wrong order - the error object is the first argument and the object found is the second one.
The .findOne method callback must have the following parameters function (err, res). So you are setting them in a reversed order.
Check http://mongoosejs.com/docs/api.html#model_Model.findOne

Node.JS & Mongoose - insert item into an array in the database

I am currently working on a project and I am stuck with inserting an item into an array/object in the database. What I am trying to do is to add the id of a 'upvoted' post to an array/list in the 'User' Collection, however, I cannot seem to get it to work.
The code for my schemas is as follows:
// this is a child scheme/sub-document
var uvpSchema = new Schema();
uvpSchema.add({
post: String
});
var dvpSchema = new Schema();
dvpSchema.add({
post: String
});
//main schema
var userSchema = new Schema({
firstname: { type: String, required: true },
lastname: { type: String, required: true },
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
upVotedPosts: [uvpSchema],
downVotedPosts: [dvpSchema],
created_at: Date,
});
And here is the code in my 'routes.js' to insert the id of the post into the array:
var newPush = {
post: postID // postID is a variable that I have already defined
};
User.findOneAndUpdate({username: req.session.user}, {$push: {upVotedPosts: newPush}}, {upsert: true, save: true}, (err, user) => {
if (err) console.log(err);
user.upVotedPosts.push(newPush);
User.save;
res.redirect(req.get('referer'));
console.log(user.upVotedPosts);
});
The error I receive in my terminal is:
{ _id: 595f68b5fadd49105813f8a4 },{ _id: 595f693d3c2c21189004b0a7 },{ _id: 595f70a2df80e0252894551b }
events.js:163
throw er; // Unhandled 'error' event
^
Thanks in advance ;-)
Route.js
User.findOneAndUpdate({username: req.session.user}, {$push: {upVotedPosts: newPush}}, {upsert: true, save: true}, (err, user) => {
if (err) console.log(err);
user.upVotedPosts.push(newPush);
User.save;
res.redirect(req.get('referer'));
console.log(user.upVotedPosts);
});
You dont need to explicitly push, since you pushed using findOneandUpdate - $push
Refer here
Secondly , its
user.save()
and not
User.save
First of all, I'd like to thank everyone's' help ;-)
I finally managed to get it partially working! My problem was that my functions were running asynchronously, causing some problems. I solved this by adding callback functions to each mongoose function.
However, the same error is still being returned, causing the server to crash. Everything else works; the new item is added to the array.
Is there anyway to ignore the error so that the server doesn't crash?

Mongoose request for id field returns id and _id

In my Mongoose schema I have an id field which has a unique ID for each document. This runs off the same system used by the default _id field like so:
var JobSchema = new mongoose.Schema({
id: { type:String, required:true, unique:true, index:true, default:mongoose.Types.ObjectId },
title: { type: String },
brief: { type: String }
});
module.exports = mongoose.model("Job", JobSchema);
Now, if I query the schema to get id and title I'd do it like this:
Job.find().select("id title").exec(function(err, jobs) {
if (err) throw err;
res.send(jobs);
});
However, I've found this returns id and title as expected, but it also return the default _id field. Why is that and how do I stop it?
Inside the find() function you can pass two parameters (criteria and projection). Projection are the fields that you want (or not). In your case you can change your code to
Job.find({}, {_id:0, id: 1, title: 1}, function(err, jobs) {
if (err) throw err;
res.send(jobs);
});
and it should do it.
There is an option to prevent the id on schema level.
For me this worked perfectly fine.
new Schema({ name: String }, { id: false });
Mongoose Docs

Recreate models using Mongoose

I want to recreate the models in database after dropping everything in it.
Mongoose (or Mongo itself )actually recreates the documents but not the indices. So is there a way to reset Mongoose so that it can recreate indices as if running the first time?
The reason why I'm using dropDatabase is because it seems easier while testing. Otherwise I would have to remove all collections one by one.
While not recommended for production use, depending on your scenario, you can add the index property to a field definition to specify you want an index created:
var animalSchema = new Schema({
name: String,
type: String,
tags: { type: [String], index: true } // field level
});
animalSchema.index({ name: 1, type: -1 }); // schema level
Or,
var s = new Schema({ name: { type: String, sparse: true })
Schema.path('name').index({ sparse: true });
Or, you can call ensureIndex on the Model (docs):
Animal.ensureIndexes(function (err) {
if (err) return handleError(err);
});

Categories