使用Mongoose动态创建集合

时间:2013-03-09 03:47:11

标签: node.js mongoose

我想让用户能够在我的Node应用程序中创建集合。我真的只看到了用mongoose收集硬编码的例子。任何人都知道是否可以使用mongoose动态创建集合?如果是这样,一个例子会非常有帮助。

基本上我希望能够在不同的集合中存储不同“事件”的数据。

即。 事件: 事件1, 事件2, ... EVENTN

用户可以创建自己的自定义事件并在该集合中存储数据。最后,每个事件可能有数百/数千行。我想让用户能够对他们的事件执行CRUD操作。我想将每个事件数据存储在不同的集合中,而不是存储在一个大集合中。

我没有一个我尝试过的例子,因为我只使用mongoose创建了“硬编码”集合。我甚至不确定我是否可以根据用户请求在mongoose中创建一个动态的新集合。

var mongoose = require('mongoose');
mongoose.connect('localhost', 'events');

var schema = mongoose.Schema({ name: 'string' });
var Event1 = mongoose.model('Event1', schema);

var event1= new Event1({ name: 'something' });
event1.save(function (err) {
  if (err) // ...
  console.log('meow');
});

如果我将'Event1'硬编码为集合,则上述效果很好。不确定我是否创建了动态集合。

var mongoose = require('mongoose');
mongoose.connect('localhost', 'events');

...

var userDefinedEvent = //get this from a client side request
...

var schema = mongoose.Schema({ name: 'string' });
var userDefinedEvent = mongoose.model(userDefinedEvent, schema);

你能这样做吗?

6 个答案:

答案 0 :(得分:18)

我认为这是一个可怕的想法,但一个问题值得回答。您需要定义一个动态名称的模式,该模式允许其中包含“任何”类型的信息。执行此操作的功能可能与此功能有点类似:

var establishedModels = {};
function createModelForName(name) {
    if (!(name in establishedModels)) {
        var Any = new Schema({ any: Schema.Types.Mixed });
        establishedModels[name] = mongoose.model(name, Any);
    }
    return establishedModels[name];
}

现在,您可以创建允许信息的模型,而不受任何限制,包括名称。我将假设一个像这样定义的对象{name: 'hello', content: {x: 1}},它由'user'提供。为了保存这个,我可以运行以下代码:

var stuff = {name: 'hello', content: {x: 1}}; // Define info.
var Model = createModelForName(name); // Create the model.
var model = Model(stuff.content); // Create a model instance.
model.save(function (err) { // Save
    if (err) {
        console.log(err);
    }
});

查询非常相似,获取模型然后进行查询:

var stuff = {name: 'hello', query: {x: {'$gt': 0}}}; // Define info.
var Model = createModelForName(name); // Create the model.
model.find(stuff.query, function (err, entries) {
    // Do something with the matched entries.
});

您必须实现代码才能保护您的查询。您不希望用户炸毁您的数据库。

答案 1 :(得分:6)

来自mongo docs:数据建模

  

在某些情况下,您可以选择存储信息   几个集合而不是单个集合。

     

考虑存储日志文档的样本集合日志   各种环境和应用。日志集合包含   以下形式的文件:

     

{log:“dev”,ts:...,info:...} {log:“debug”,ts:...,info:...}

     

如果文档总数较少,您可以将文档分组   按类型收集。对于日志,请考虑维护不同的日志   集合,例如logs.dev和logs.debug。 logs.dev集合   将仅包含与开发环境相关的文档。

     

一般来说,拥有大量藏品并不重要   性能损失并导致非常好的性能。不同   集合对于高吞吐量批处理非常重要。

答案 2 :(得分:4)

  

说我有20个不同的事件。每个事件都有100万个条目......因此,如果这是一个集合,我将不得不按事件筛选每个CRUD操作的集合。

我建议你将所有事件保存在同一个集合中,特别是如果事件名称依赖于客户端代码,因此可能会发生变化。而是索引名称和用户引用。

mongoose.Schema({
  name: { type: String, index: true },
  user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', index: true } 
});

此外,我认为你的问题有点落后(但我可能会弄错)。您是在用户的上下文中查找事件,还是在事件名称的上下文中查找用户?我感觉它是前者,你应该在用户引用上进行分区,而不是首先对事件名称进行分区。

如果您不需要为用户查找所有事件,只需要同时处理用户和事件名称,您可以使用复合索引:

schema.index({ user: 1, name: 1 });

如果您要处理数百万个文档,请务必关闭自动索引:

schema.set('autoIndex', false);

这篇文章有关于命名集合和使用特定模式的有趣内容:

How to access a preexisting collection with Mongoose?

答案 3 :(得分:0)

您可以尝试以下方法:

var createDB = function(name) {

  var connection = mongoose.createConnection(
    'mongodb://localhost:27017/' + name);

  connection.on('open', function() {
    connection.db.collectionNames(function(error) {
      if (error) {
        return console.log("error", error)
      }
    });

  });
  connection.on('error', function(error) {
    return console.log("error", error)
  });

}
使用connection.db.collectionNames获取集合名称非常重要,否则将不会创建数据库。

答案 4 :(得分:0)

此方法最适合我,此示例为每个用户创建动态集合,每个集合将仅保存相应的用户信息(登录详细信息),首先在单独的文件中声明函数dinamycModel:example model.js

/* model.js */
'use strict';

var mongoose = require('mongoose'),
  Schema = mongoose.Schema;


  function dinamycModel(suffix){
  var addressSchema = new Schema(
    {
        "name" : {type: String, default: '',trim: true},
        "login_time" : {type: Date},
        "location" : {type: String, default: '',trim: true},
    }
  );

     return mongoose.model('user_' + suffix, addressSchema);

  }

module.exports = dinamycModel;

在Controller File示例user.js中,第一个函数创建动态集合,第二个函数将数据保存到特定集合

/* user.js */
var  mongoose = require('mongoose'),

 function CreateModel(user_name){//function to create collection , user_name  argument contains collection name

  var Model  = require(path.resolve('./model.js'))(user_name);

}

function save_user_info(user_name,data){//function to save user info , data argument contains user info
     var UserModel  = mongoose.model(user_name) ;
     var usermodel  = UserModel(data);
              usermodel.save(function (err) {

               if (err) {
                  console.log(err);
                } else {
                 console.log("\nSaved");
                }
           });
}

答案 5 :(得分:0)

是的,我们可以做到。我已经尝试了它及其工作原理。

参考代码:

app.post("/",function(req,res){

  var Cat=req.body.catg;
  const link= req.body.link;
  const rating=req.body.rating;
  Cat=mongoose.model(Cat,schema);
  const item=new Cat({
  name:link,
  age:rating
  });
 item.save();
  res.render("\index");
});