dynamic创build收集瓦特/mongoose

我想让用户能够在我的Node应用程序中创build集合。 我真的只看到mongoose藏品中硬编码的例子。 任何人都知道是否有可能dynamic创build集合w / mongoose? 如果是这样,一个例子会非常有帮助。

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

IE事件:event1,event2,… eventN

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

我没有真正的例子,因为我只用mongoose创build了“硬编码”的集合。 我甚至不确定我可以根据用户请求在mongoose中创build一个新的集合。

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'作为一个集合。 不知道我创build了一个dynamic集合。

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

你能做到吗?

我认为这是一个可怕的想法,但一个问题值得回答。 您需要定义一个dynamic名称的架构,允许其中包含“任何”types的信息。 做这个的函数可能和这个函数有点类似:

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

现在,您可以创build允许没有任何限制的信息模型,包括名称。 我将假设一个像这样定义的对象,这个对象是由用户提供的{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. }); 

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

从这里的mongo文档:数据build模

在某些情况下,您可能select将信息存储在多个集合中,而不是单个集合中。

考虑一个示例收集日志,其中存储了各种环境和应用程序的日志文档。 日志收集包含以下forms的文档:

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

如果文件总数很less,您可以将文件按照types分组。 对于日志,请考虑维护不同的日志集合,例如logs.dev和logs.debug。 logs.dev集合将只包含与开发环境相关的文档。

一般来说,collections数量多,没有明显的性能损失,效果非常好。 不同的集合对于高吞吐量批处理非常重要。

说我有20个不同的事件。 每个事件有一百万个条目…因此,如果这是所有在一个集合中,我将不得不按事件筛选收集每个CRUD操作。

我build议你把所有的事件保存在同一个集合中,特别是如果事件名称取决于客户端代码,并且因此可能会改变。 而是索引名称和用户参考。

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

此外,我认为你有一些倒退的问题(但我可能会误解)。 您是在用户的上下文中查找事件还是在事件名称的上下文中查找用户? 我有一种感觉,它是前者,你应该在用户引用上进行分区,而不是事件名称。

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

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

如果您正在处理数百万个文档,请确保closures自动索引:

 schema.set('autoIndex', false); 

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

如何访问Mongoose预先存在的collections?

你可以试试以下内容:

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