26

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

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

IE 事件:event1, event2, ... eventN

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

我没有真正尝试过的示例,因为我只用猫鼬创建了“硬编码”集合。我什至不确定是否可以根据用户请求在 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);

你能做到吗?

4

7 回答 7

22

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

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}},它是由“用户”提供的。为了保存它,我可以运行以下代码:

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

您将不得不实施代码来保护您的查询。您不希望用户炸毁您的数据库。

于 2013-03-09T10:13:00.440 回答
6

From mongo docs here: data modeling

In certain situations, you might choose to store information in several collections rather than in a single collection.

Consider a sample collection logs that stores log documents for various environment and applications. The logs collection contains documents of the following form:

{ log: "dev", ts: ..., info: ... } { log: "debug", ts: ..., info: ...}

If the total number of documents is low you may group documents into collection by type. For logs, consider maintaining distinct log collections, such as logs.dev and logs.debug. The logs.dev collection would contain only the documents related to the dev environment.

Generally, having large number of collections has no significant performance penalty and results in very good performance. Distinct collections are very important for high-throughput batch processing.

于 2014-01-04T18:55:16.350 回答
5

假设我有 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);

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

如何使用 Mongoose 访问预先存在的集合?

于 2013-11-28T05:41:43.967 回答
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 获取集合名称很重要,否则将不会创建数据库。

于 2015-05-01T16:25:38.653 回答
0

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

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

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


  function dynamicModel(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 = dynamicModel;

在控制器文件示例 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");
                }
           });
}
于 2019-04-09T11:12:16.040 回答
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");
});
于 2020-01-22T14:49:52.713 回答
0

我试过Magesh varan参考代码,

这段代码对我有用

   router.post("/auto-create-collection", (req, res) => {
  var reqData = req.body; // {"username":"123","password":"321","collectionName":"user_data"}

  let userName = reqData.username;
  let passWord = reqData.password;
  let collectionName = reqData.collectionName;

  // create schema
  var mySchema = new mongoose.Schema({
    userName: String,
    passWord: String,
  });

  // create model
  var myModel = mongoose.model(collectionName, mySchema);

  const storeData = new myModel({
    userName: userName,
    passWord: passWord,
  });
  storeData.save();

  res.json(storeData);
});
于 2022-02-02T05:11:49.573 回答