node.js 使用 Mongoose 动态创建集合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15306916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamically create collection with Mongoose
提问by lostintranslation
I want to give users the ability to create collections in my Node app. I have really only seen example of hard coding in collections with mongoose. Anyone know if its possible to create collections dynamically with mongoose? If so an example would be very helpful.
我想让用户能够在我的 Node 应用程序中创建集合。我真的只见过猫鼬集合中硬编码的例子。任何人都知道是否可以使用猫鼬动态创建集合?如果是这样,一个例子将非常有帮助。
Basically I want to be able to store data for different 'events' in different collections.
基本上我希望能够在不同的集合中存储不同“事件”的数据。
I.E. Events: event1, event2, ... eventN
IE 事件: event1, event2, ... eventN
Users can create there own custom event and store data in that collection. In the end each event might have hundreds/thousands of rows. I would like to give users the ability to perform CRUD operations on their events. Rather than store in one big collection I would like to store each events data in a different collection.
用户可以在那里创建自己的自定义事件并将数据存储在该集合中。最后,每个事件可能有数百/数千行。我想让用户能够对他们的事件执行 CRUD 操作。我想将每个事件数据存储在不同的集合中,而不是存储在一个大集合中。
I don't really have an example of what I have tried as I have only created 'hard coded' collections with mongoose. I am not even sure I can create a new collection in mongoose that is dynamic based on a user request.
我真的没有我尝试过的例子,因为我只用猫鼬创建了“硬编码”集合。我什至不确定我是否可以根据用户请求在 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');
});
Above works great if I hard code 'Event1' as a collection. Not sure I create a dynamic collection.
如果我将“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);
Can you do that?
你能做到吗?
采纳答案by lostintranslation
From mongo docs here: data modeling
来自这里的 mongo 文档:数据建模
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.
在某些情况下,您可能会选择将信息存储在多个集合中而不是单个集合中。
考虑存储各种环境和应用程序的日志文档的示例收集日志。日志集合包含以下形式的文档:
{日志:“开发”,ts:...,信息:...} {日志:“调试”,ts:...,信息:...}
如果文档总数较少,您可以按类型将文档分组到集合中。对于日志,请考虑维护不同的日志集合,例如 logs.dev 和 logs.debug。logs.dev 集合将仅包含与开发环境相关的文档。
通常,拥有大量集合不会造成显着的性能损失,并且会产生非常好的性能。不同的集合对于高吞吐量批处理非常重要。
回答by Hozuki
I believe that this is a terrible idea to implement, but a question deserves an answer. You need to define a schema with a dynamic name that allows information of 'Any' type in it. A function to do this may be a little similar to this function:
我相信这是一个可怕的想法,但一个问题值得回答。您需要定义一个具有动态名称的模式,该名称允许其中包含“任何”类型的信息。执行此操作的函数可能与此函数有点相似:
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];
}
Now you can create models that allow information without any kind of restriction, including the name. I'm going to assume an object defined like this, {name: 'hello', content: {x: 1}}, which is provided by the 'user'. To save this, I can run the following code:
现在,您可以创建允许信息不受任何限制(包括名称)的模型。我将假设一个像这样定义的对象{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);
}
});
Queries are very similar, fetch the model and then do a query:
查询非常相似,获取模型然后进行查询:
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.
});
You will have to implement code to protect your queries. You don't want the user to blow up your db.
您将必须实施代码来保护您的查询。您不希望用户炸毁您的数据库。
回答by AJcodez
Say I have 20 different events. Each event has 1 million entries... As such if this is all in one collection I will have to filter the collection by event for every CRUD op.
假设我有 20 个不同的事件。每个事件都有 100 万个条目……因此,如果这都在一个集合中,我将不得不为每个 CRUD 操作按事件过滤集合。
I would suggest you keep all events in the same collection, especially if event names depend on client code and are thus subject to change. Instead, index the name and user reference.
我建议您将所有事件保存在同一个集合中,特别是如果事件名称依赖于客户端代码,因此可能会发生变化。相反,索引名称和用户引用。
mongoose.Schema({
name: { type: String, index: true },
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', index: true }
});
Furthermore I think you came at the problem a bit backwards (but I might be mistaken). Are you finding events within the context of a user, or finding users within the context of an event name? I have a feeling it's the former, and you should be partitioning on user reference, not the event name in the first place.
此外,我认为您的问题有点倒退(但我可能会弄错)。您是在用户上下文中查找事件,还是在事件名称上下文中查找用户?我有一种感觉是前者,您应该首先根据用户引用而不是事件名称进行分区。
If you do not need to find all events for a user and just need to deal with user and event name together you could go with a compound index:
如果您不需要查找用户的所有事件而只需要一起处理用户和事件名称,您可以使用复合索引:
schema.index({ user: 1, name: 1 });
If you are dealing with millions of documents, make sure to turn off auto index:
如果您正在处理数百万个文档,请确保关闭自动索引:
schema.set('autoIndex', false);
This post has interesting stuff about naming collections and using a specific schema as well:
这篇文章有关于命名集合和使用特定模式的有趣内容:
回答by Daniele Urania
You could try the following:
您可以尝试以下操作:
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)
});
}
回答by Prem Sanil
This method works best for me , This example creates dynamic collection for each users , each collection will hold only corresponding users information (login details), first declare the function dynamicModel in separate file : example model.js
这个方法最适合我,这个例子为每个用户创建动态集合,每个集合将只保存相应的用户信息(登录详细信息),首先在单独的文件中声明函数 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;
In controller File example user.js,first function to create dynamic collection and second function to save data to a particular collection
在控制器文件示例 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");
}
});
}
回答by Magesh varan
yes we can do that .I have tried it and its working.
是的,我们可以做到这一点。我已经尝试过了,而且效果很好。
REFERENCE CODE:
参考代码:
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");
});

