我想让用户能够在我的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);
你能这样做吗?
答案 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);
这篇文章有关于命名集合和使用特定模式的有趣内容:
答案 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)
});
}
答案 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");
});