Хранение и извлечение объектов JavaScript в/из MongoDB

В настоящее время я играю с node.js и MongoDB с помощью драйвера node -mongo.

Я немного тестировал использование консоли Mongo для хранения и извлечения объектов JS. Я понял, что если я храню объект, содержащий функции/методы, методы и функции также будут храниться в коллекции. Это интересно, поскольку я думал, что функции не могут быть сохранены в MongoDB (за исключением коллекции system.js, как предложено Mongo docs).
Также он не только сохранит методы, но фактически каждый метод и член цельной цепи прототипов объекта. Кроме того, мне не нравится это поведение и считаю, что это неинтуитивно, я не должен этого делать.

Я собирался управлять пользователями в коллекции Mongo. Для этого у меня есть объект User, содержащий все методы пользователей, которые работают в качестве прототипа для каждого экземпляра пользователя. Сам пользовательский объект будет содержать только атрибуты пользователей.

Если я храню пользователя в коллекции Mongo, я хочу только сохранить собственные свойства объекта пользователя. Никаких прототипов и, особенно, прототипов. В настоящее время я не понимаю, как это сделать. Параметры, которые, как я понял, могут работать:

  • создание мелкой копии с использованием foreach и hasOwnProperty и сохранение этой копии в коллекции.
  • Добавить атрибут данных для каждого пользователя, который содержит все атрибуты объекта и может быть сохранен в коллекции.
  • Это, как мне показалось, написало это: я также мог бы установить все свойства прототипов, чтобы они не перечислили, что должно помешать их хранить в коллекции.

Однако у меня есть те же проблемы, что и в других случаях: при загрузке пользователя из коллекции. AFAIK не существует способа изменить прототип объектов в JavaScript после его создания. И также нет способа указать прототип для использования, когда Mongo создает объекты, извлеченные из коллекции. Поэтому в основном я всегда получаю объекты, которые наследуются от Object using Mongo. Насколько я могу судить, у меня есть 2 варианта восстановления полезного пользовательского объекта с этого момента:

  • Создайте новый объект, наследующий пользователя, и скопируйте каждый атрибут объекта результата на вновь созданный объект. (Совместимость с механизмами хранения 1 и 3)
  • Создайте новый объект, наследующий пользователя, и сохраните объект результата как атрибут данных для вновь созданного объекта. (Совместимость с механизмом сохранения 2)

Являются ли мои предположения, особенно о возможности указать прототип результатов запроса, исправить? Какой правильный способ сделать это и почему? Я, конечно, не первый человек, пытающийся сохранить и воскресить объекты в/из MongoDB с помощью node.js.

В настоящее время я бы пошел с подходом 2/2. Мне это не очень нравится, но это самый эффективный и единственный, который работает с API. Тем не менее, я бы скорее услышал, что на самом деле API ничего не делает, но я не знаю, как правильно его использовать. Поэтому, пожалуйста, просветите меня:)

Ответ 1

Недавно я понял, что на самом деле можно изменить прототип объектов в V8/ node. Хотя это не в стандарте, это возможно в разных браузерах и особенно в V8/node!

function User(username, email) {
    this.username = username;
    this.email = email;
}

User.prototype.sendMail = function (subject, text) {
    mailer.send(this.email, subject, text);
};

var o = {username: 'LoadeFromMongoDB', email: '[email protected]'};
o.__proto__ = User.prototype;
o.sendMail('Hello, MongoDB User!', 'You where loaded from MongoDB, but inherit from User nevertheless! Congratulations!');

Это используется во всех модулях и плагинах - даже основные модули используют эту технику, хотя это не стандарт ECMAScript. Поэтому я думаю, что это безопасно использовать в node.js.

Ответ 2

Я не уверен, что я точно задаю вам вопрос... но пришло в голову одно: вы проверили Mongoose ORM? (http://mongoosejs.com/)

Это дает вам много вариантов, когда дело доходит до определения моделей и методов. В частности, может быть интересен "Виртуальный" (http://mongoosejs.com/docs/virtuals.html).

В любом случае, надеюсь, что это поможет кому-то!