所以,我想创建一个基于客户端的分区模式,我将集合名称设置为function(),我的伪代码是这样的:
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);
});
这是否可以通过moongose实现,以便读取和写入都能按预期工作?
答案 0 :(得分:4)
你好,你只需要用你的dinamically名称声明架构模型,如下所示:
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;
所以在你的代码中你可以做到这一点:
var userAdress = require('address.js')(id_user);
var usrAdrs1 = new userAddress({...});
userAdrs1.save();
现在去你的mongo shell&列表集合(使用mydb然后显示集合),您将看到一个带有uid前缀的地址的新集合。通过这种方式,mongoose将为每个不同的用户uid创建一个新的集合地址。
干杯...
答案 1 :(得分:2)
集合名称逻辑在整个Moongose代码库中都是硬编码的,因此客户端分区现在就不可能了。
我的解决方案是直接使用mongo驱动程序 -
https://github.com/mongodb/node-mongodb-native
事实证明这很好,与驱动程序一起使用的灵活性直接允许所需的一切,并且Moongose开销在任何情况下似乎都没有增加太多。
答案 2 :(得分:1)
Gomosoft的解决方案有效。它需要一些修正,但这个想法很好用。 以上解决方案仅在第一次使用。如果您尝试向同一个集合发送第二个请求,则会尝试覆盖已定义的模型时抛出错误。所以我不得不按如下方式调整它:
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(...);
});
因为我正在检查 myRating 是否未定义,所以它只会创建此引用一次。所以不会发生错误。 希望这会有所帮助。
答案 3 :(得分:1)
我的建议是动态创建模型:
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];
};
然后您就可以使用
const result = dynamicModel("YourCollectionName").findOne({})
答案 4 :(得分:0)
实现:
//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 :(得分:0)
我正在添加 Javier Gomez 的答案,以解决 Exis Zang 的“OverwriteModelError:无法覆盖 xxx 模型一旦编译”问题。 Schema 模型文件可以存储基于单例模式的动态模型数组。如果该模型已经存在,则返回它,否则使用 new 创建它,存储它并返回它:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const Addresses = {}
// 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);
}
// this function will store the model in the Addresses object
// on subsequent calls, if it exists, it will return it from the array
function getAddressModel(prefix) {
if (!Addresses[prefix]) {
Addresses[prefix] = new DynamicSchema(prefix)
}
return Addresses[prefix]
}
//now we export getAddressModel function
module.exports = getAddressModel;
答案 6 :(得分:0)
To Create a dynamic collection follow the below steps,
const mongoose = require('mongoose');
function createCompanyDynamicSchema(prefix) {
let collectionName = prefix + '_company';
companySchema = new mongoose.Schema(
{
name: { type: String },
enabled: { type: Number, default: 1 },
},
{ timestamps: true },
{ versionKey: false },
{ strict: false }
);
collectionName = mongoose.model(collectionName, companySchema);
return collectionName;
}
module.exports = { createCompanyDynamicSchema };
To call this method from any file,
let companySchema = require('./schema');
_this.createCompany = function () {
return new Promise(async (resolve, reject) => {
let companyCollection = companySchema.createCompanyDynamicSchema('IO');
let addr = new companyCollection({ first_name: 'test' });
addr.save();
});
};
To query from dynamically created collection,
_this.getCompany = function () {
return new Promise(async (resolve, reject) => {
let companyCollection = companySchema.createCompanyDynamicSchema('IO');
let data = await companyCollection.model('IO_users').find();
console.log(data);
});
};