Подтвердить что ты не робот

Динамически создавать коллекцию с помощью Mongoose

Я хочу дать пользователям возможность создавать коллекции в моем приложении Node. Я действительно только видел пример жесткого кодирования в коллекциях с мангуста. Кто-нибудь знает, можно ли создавать коллекции динамически с mongoose? Если бы такой пример был бы очень полезен.

В основном я хочу иметь возможность хранить данные для разных "событий" в разных коллекциях.

т.е. Мероприятия: 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);

Вы можете это сделать?

4b9b3361

Ответ 1

Из mongo docs здесь: моделирование данных

В некоторых ситуациях вы можете хранить информацию в несколько коллекций, а не в одной коллекции.

Рассмотрим примеры журналов коллекции, в которых хранятся документы журнала для различные среды и приложения. Коллекция журналов содержит документы следующего вида:

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

Если общее количество документов невелико, вы можете группировать документы в коллекция по типу. Для журналов рассмотрим возможность сохранения отдельного журнала коллекций, таких как logs.dev и logs.debug. Коллекция logs.dev будет содержать только документы, связанные с средой dev.

Как правило, наличие большого количества коллекций не имеет значительных и дает очень хорошую производительность. отчетливый коллекции очень важны для пакетной обработки с высокой пропускной способностью.

Ответ 2

Я считаю, что это ужасная идея для реализации, но вопрос заслуживает ответа. Вам нужно определить схему с динамическим именем, которая позволяет в ней вводить информацию типа "Любой". Функция для этого может быть немного похожа на эту функцию:

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

Вам нужно будет реализовать код для защиты ваших запросов. Вы не хотите, чтобы пользователь взорвал ваш db.

Ответ 3

Скажем, у меня 20 разных событий. Каждое событие имеет 1 миллион записей... Таким образом, если это все в одной коллекции, мне придется фильтровать коллекцию по событию для каждого 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?

Ответ 4

Вы можете попробовать следующее:

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

}