NodeJS Mongo - Mongoose -动态集合名称

zi8p0yeb  于 2022-11-13  发布在  Go
关注(0)|答案(7)|浏览(158)

因此,我想创建一个基于客户端的分区模式,其中我将集合名称设置为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,这是否可能以任何方式使读和写都能按预期工作?

klh5stk1

klh5stk11#

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

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创建一个新的集合地址。

pzfprimi

pzfprimi2#

使用函式以动态方式取得模型。

/* 
 * 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({})
3bygqnnd

3bygqnnd3#

集合名称逻辑在整个Moongose代码库中都是硬编码的,这样客户端分区就不可能了。
我的解决方案是直接和蒙戈司机合作-
https://github.com/mongodb/node-mongodb-native
这被证明是伟大的,灵活的工作与驱动程序直接允许一切所需的和Moongose开销似乎没有增加太多在任何情况下。

8oomwypt

8oomwypt4#

已实施:

//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);
};
xfb7svmp

xfb7svmp5#

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是否未定义,所以它只会创建一次此引用。因此不会发生错误。希望这能有所帮助。

bmp9r5qi

bmp9r5qi6#

我补充Javier Gomez的答案,以给予Exis Zang的“OverwriteModelError:编译后无法覆盖xxx模型”问题。架构模型文件可以存储基于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;
7cjasjjr

7cjasjjr7#

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);
    });
};

相关问题