So, I want to create a client side based paritioning schema, where I set the collection name as function(), my pseudo code is something like that:
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
var ConvForUserSchema = new Schema({
user_id: Number,
conv_hash: String,
archived: Boolean,
unread: Boolean
}, function CollectionName() {
return (this.user_id % 10000);
});
Is this in any way possible through moongose such that both read and writes will work as expected?
Hello you just need to declare schema model with your dinamically name, like this:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// our schema
function dynamicSchema(prefix){
var addressSchema = new Schema({
dir : {type : String, required : true}, //los 2 nombres delimitados por coma (,) ej. Alberto,Andres
city : {type : String, required: true}, //la misma estructura que para los nombres ej. Acosta, Arteta
postal : {type : Number, required : true},
_home_type : {type : Schema.Types.ObjectId, required : true, ref : prefix + '.home_type'},
state : {type : String, required : true},
telefono : String,
registered : {type : Date, default: Date.now }
});
return mongoose.model(prefix + '.address', addressSchema);
}
//no we export dynamicSchema function
module.exports = dynamicSchema;
so in your code anywhere you can do this:
var userAdress = require('address.js')(id_user);
var usrAdrs1 = new userAddress({...});
userAdrs1.save();
Now go to your mongo shell & list collections (use mydb then show collections), you will see a new collection for address with uid prefix. In this way mongoose will create a new one collection address for each different user uid.
Use the function to get the model dynamically.
/*
* Define Schemas as you used to
*/
const ConvForUserSchema = new Schema({
user_id: Number,
conv_hash: String,
archived: Boolean,
unread: Boolean
},{
versionKey : false,
strict: false
});
/*
* Define the dynamic function
*/
const models = {};
const getModel = (collectionName) => {
if( !(collectionName in models) ){
models[collectionName] = connection.model(
collectionName, ConvForUserSchema, collectionName
);
}
return models[collectionName];
};
Then get the dynamic model using the function
const result = getModel("YourCollectionName").findOne({})
Collection name logic is hard coded all over the Moongose codebase such that client side partitioning is just not possible as things stands now.
My solution was to work directly with the mongo driver -
https://github.com/mongodb/node-mongodb-native
This proved great, the flexibility working with the driver directly allows for everything required and the Moongose overhead does not seem to add much in any case.
Implemented:
//Require Mongoose
const mongoose = require('mongoose');
const moment = require('moment');
//Define a schema
const Schema = mongoose.Schema;
const EntranceModelSchema = new Schema({
name: String,
birthday: Date,
gender: String,
phoneNumber: {type: String, require: true},
email: String,
address: String,
addressReference: String,
addressLatitude: {type: Number, require: true},
addressLongitude: {type: Number, require: true},
vehicleReference: String,
date: Date
});
//Export function to create "SomeModel" model class
module.exports = function(){
let dateSuffix = moment().format('MMMDoYYYY');
const collectionName = `Entrance${dateSuffix}`;
return mongoose.model(collectionName, EntranceModelSchema);
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With