How to set "capped" after collection is created? - node.js

I am attempting to set a capped parameter to my collection within my mongoose.Schema that did not include capped at first.
Any help welcome.
My Schema:
const mongoose = require('mongoose')
var Schema = mongoose.Schema;
var userSchema = new Schema({
name: { type: String, required: true },
email: { type: String },
password: { type: String },
isAdmin: {type: Boolean, default: false},
avatar: { type: String },
joinDate: { type: Date, default: Date.now() },
},{ autoCreate: true, capped : 1024})
userSchema.set('timestamps', true);
const Users = mongoose.model('Users', userSchema)
module.exports = Users;
I get following error:
Error: A non-capped collection exists with the name: users
To use this collection as a capped collection, please first convert it.

Seems like you have already created a users collection in your database. So to convert it into a capped run below command either in mongoshell or robomongo
db.runCommand( { convertToCapped: 'users', size: 1024 } )

Related

How to create a dynamic nested mongoose document with the same schema on multiple levels

Before everyone tells me I can't call a const before initializing, I do know that.
But I think this is the simplest way to render the concept I have in mind, (where any subdocument within the replies array also has the same schema as the parent, and documents within the replies array of those subdocuments also having the same schema). I would really appreciate anyone's input.
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
var commentSchema = new mongoose.Schema({
content: String,
createdAt: {
type: Date,
default: Date.now
},
score: {
type: Number,
default: 1
},
username: {
type: String,
lowercase: true
},
parent: {
type: Schema.Types.ObjectId,
ref: 'comment'
},
replyingTo: String,
replies: [commentSchema]
});
module.exports = mongoose.model("comment", commentSchema);
Since a const can't be called before initialization, to fix this issue the parent schema should be called on the children array after initialization the code below:
commentSchema.add({ replies: [commentSchema] })
The final result should look like this:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const commentSchema = new mongoose.Schema({
content: String,
createdAt: {
type: Date,
default: Date.now
},
score: {
type: Number,
default: 1
},
username: {
type: String,
lowercase: true
},
parent: {
type: Schema.Types.ObjectId,
ref: 'comment'
},
replyingTo: String,
});
commentSchema.add({ replies: [commentSchema] })

How to rename a collection without loosing data of collection in Mongoose

I am using Mongoose in my NodeJs project. I want to rename my collection from OldCollectionName to NewCollectionName.
I tried following:
Mongoose.connection.collection('OldCollectionName').rename('NewCollectionName');
But this is making my collection empty. Can someone suggest how can I change the collection name without loosing my collection data? I need all the data from OldCollectionName in NewCollectionName as well.
I have following schema for my model
const Mongoose = require('mongoose');
const mongooseSequence = require('mongoose-sequence');
const Schema = Mongoose.Schema;
var collectionSchema = new Schema({
collectionIdAutoIncrement: { type: Number,unique: true,index:true,sparse:true},
fieldName: {
type: String,
default: ''
},
otherCollectionId: {
type: Schema.Types.ObjectId,
required: true,
ref: "OtherCollection",
},
created: { type: Date, default: Date.now },
updated: { type: Date},
});
collectionSchema.plugin(mongooseSequence, { inc_field: 'collectionIdAutoIncrement' });
var oldCollection = Mongoose.model('OldCollectionName', collectionSchema);

Mongoose - Reference a field from another table

I have two tables: Post and User and I want to reference the User name in the Post table.
I can reference the ID but I also need the name.
User model:
const userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
})
module.exports = mongoose.model("User", userSchema)
Post model:
const { ObjectId } = mongoose.Schema.Types
const postSchema = new mongoose.Schema({
title: {
type: String,
required: true,
},
author: {
type: ObjectId,
ref: "User",
},
})
module.exports = mongoose.model("Post", postSchema)
In the doc they said:
Note: ObjectId, Number, String, and Buffer are valid for use as refs.
However, you should use ObjectId unless you are an advanced user and
have a good reason for doing so.
However I couldn't find an example on how I can do this.

node mongoose update two collections

I have two schemas, a "projects" schema, and an "applications" schema.
What is the most efficient way of creating a new entry in a collection and updating an existing entry in another collection based on data inside the new entry? Can I avoid making multiple API requests and somehow run a "stored procedure" on the mongoDB end to handle updating the Projects collection when there is a change in the Applications collection?
In this scenario, ideally when an application for a project is created, a new entry is created in the Applications collection and the Project in the Projects collection is updated to reflect the information in the Application.
Can I do this without making multiple api requests?
Project Schema:
// models product.js
const mongoose = require('mongoose');
const { ObjectId } = mongoose.Schema;
const projectSchema = new mongoose.Schema({
name: {
type: String,
trim: true,
required: true,
maxlength: 32
},
applications: {
type: Number,
default: 0
},
created_by: {
type: ObjectId,
ref: 'User'
},
applicants: {
type: Array,
default: []
}
}, {timestamps: true}
);
module.exports = mongoose.model("Project", projectSchema);
Application Schema:
const mongoose = require('mongoose');
const applicationSchema = new mongoose.Schema({
applicantId: {
type: ObjectId,
ref: 'User'
},
ownerId: {
type: ObjectId,
ref: 'User'
},
projectId: {
type: ObjectId,
ref: 'Project'
}
}, {timestamps: true});
module.exports = mongoose.model("Application", applicationSchema);
Note that these are separate schemas because they each carry around 15 fields, i've trimmed them down to post this question.
I suggest to use hooks for mongoose model, there is a post save hook which you can use on Application model to update Project and increment application count.
EDIT - Added Pseudo Code
Project Model
// models -> project.js
const mongoose = require('mongoose');
const {
ObjectId
} = mongoose.Schema;
const projectSchema = new mongoose.Schema({
name: {
type: String,
trim: true,
required: true,
maxlength: 32
},
applications: {
type: Number,
default: 0
},
created_by: {
type: ObjectId,
ref: 'User'
},
applicants: {
type: Array,
default: []
}
}, {
timestamps: true
});
projectSchema.statics = {
/**
* Find project by _id
*
* #param {ObjectId} _id
* #api private
*/
get: function (_id) {
return this.findOne({
_id
})
.exec();
}
}
module.exports = mongoose.model("Project", projectSchema);
Application Model
const mongoose = require('mongoose');
const projectModel = require("./project")
const applicationSchema = new mongoose.Schema({
applicantId: {
type: ObjectId,
ref: 'User'
},
ownerId: {
type: ObjectId,
ref: 'User'
},
projectId: {
type: ObjectId,
ref: 'Project'
}
}, {
timestamps: true
});
// Async hook
applicationSchema.post('save', function (doc, next) {
const relatedProject = projectModel.get(doc.projectId);
relatedProject.applications++;
relatedProject.save();
next();
});
module.exports = mongoose.model("Application", applicationSchema);

how to define a trigger in a mongoose schema

is there any kind of trigger at mongoose model level which provide the capability to set the value of the open field = false when the number of the members collection reaches 100?
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var listSchema = new Schema({
name: {
type: String,
required: true,
trim: true
},
desc: {
type: String
},
open: {
type: Boolean,
default: true
},
members: [{
userid: {
type: Schema.Types.ObjectId, ref: 'User'
},
prId: {
type: Schema.Types.ObjectId, ref: 'PR'
},
checkedIn: {
type: Boolean
}
}]
});
module.exports = mongoose.model('List', listSchema);
Triggers are not available in mongo. It's hard to say why you want to change documents when collection reaches some limit by maybe capped collection is what you really want?
new Schema({..}, { capped: { size: 1024, max: 100 } });
size is maximum collection size in bytes and max is maximum number of documents that can be inserted in collection.

Resources