8

所以,我想创建一个基于客户端的分区模式,我将集合名称设置为 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以任何方式实现,以使读写都按预期工作?

4

7 回答 7

14


您好,您只需要使用您的动态名称声明模式模型,如下所示:

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;

因此,在您的代码中,您可以在任何地方执行此操作:

var userAdress = require('address.js')(id_user);
var usrAdrs1 = new userAddress({...});
    userAdrs1.save();

现在转到您的 mongo shell 和列表集合(使用 mydb 然后显示集合),您将看到带有 uid 前缀的地址的新集合。这样mongoose就会为每个不同的用户uid创建一个新的收集地址。

于 2014-06-10T00:19:09.063 回答
9

使用该函数动态获取模型。

/* 
 * 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];
};

然后使用函数得到动态模型

const result = getModel("YourCollectionName").findOne({})
于 2019-04-18T08:30:36.607 回答
6

集合名称逻辑在整个 Moongose 代码库中都是硬编码的,因此客户端分区就像现在这样是不可能的。

我的解决方案是直接使用 mongo 驱动程序 -

https://github.com/mongodb/node-mongodb-native

事实证明这很好,直接与驱动程序一起工作的灵活性允许所需的一切,而且在任何情况下,Moongose 开销似乎都不会增加太多。

于 2013-07-24T07:21:54.683 回答
3

实施的:

//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);
};
于 2018-05-24T04:13:38.440 回答
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是否未定义,所以它只会创建一次此引用。所以不会出现错误。希望这可以帮助。

于 2017-03-29T19:34:39.483 回答
0

我正在添加 Javier Gomez 的答案,以解决 Exis Zang 的“OverwriteModelError:一旦编译后无法覆盖 xxx 模型”问题。Schema 模型文件可以存储基于 Singleton 模式的动态模型数组。如果该模型已经存在,则返回它,否则使用 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;
于 2021-01-23T04:09:12.033 回答
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);
    });
};
于 2021-08-01T13:43:21.190 回答