问题
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?
回答1:
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 dinamycSchema(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 dinaymicSchema function
module.exports = dinamycModel;
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.
Cheers...
回答2:
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.
回答3:
My suggestion is create model dynamically:
let dynamicModels = {};
const ConvForUserSchema = new Schema({
user_id: Number,
conv_hash: String,
archived: Boolean,
unread: Boolean
},{
versionKey : false,
strict: false
});
const dynamicModel = (collectionName) => {
if( !(collectionName in dynamicModels) ){
dynamicModels[collectionName] = connection.model(collectionName, ConvForUserSchema, collectionName);
}
return dynamicModels[collectionName];
};
then you can use
const result = dynamicModel("YourCollectionName").findOne({})
回答4:
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);
};
回答5:
Gomosoft's solution works. It needs some amends but the idea works nicely. The above solution works only the first time. If you are trying to send a second request to the same collection, it will throw an error for trying to overwrite the model that is already defined. So I had to tweak it as follows:
var Rating = require('./app/models/rating');
var myRating;
router.route('/ratings/:user_id')
.post(function(req,res){
var user_id = req.params.user_id;
if(myRating == undefined){
myRating = Rating(user_id);
}
...
rating.save(...);
});
Because I'm checking if myRating is undefined, it will create this reference only once. So no errors will occur. Hope this helps.
来源:https://stackoverflow.com/questions/17808739/nodejs-mongo-mongoose-dynamic-collection-name