在 MongoDB 中存储和检索 JavaScript 对象
我目前正在使用node-mongo-native 驱动程序来使用node.js 和MongoDB。
我使用 Mongo 控制台存储和检索 JS 对象进行了一些测试。我发现,如果我存储一个包含函数/方法的对象,那么方法和函数也将存储在集合中。这很有趣,因为我认为函数不能存储在 MongoDB 中(system.js 集合除外,正如 Mongo 文档)。
此外,它不仅会存储方法,而且实际上会存储对象整个原型链的每个方法和成员。除此之外,我不喜欢这种行为,并且认为这是不直观的,我不应该这样做。
我打算管理 Mongo 集合中的用户。为此,我有一个 User 对象,其中包含作为每个用户实例的原型的所有用户方法。用户对象本身仅包含用户属性。
如果我将用户存储在 Mongo 集合中,我只想存储用户对象自己的属性。没有原型成员,尤其是没有原型方法。目前我不知道如何干净地做到这一点。我认为可能有效的选项是:
- 使用 foreach 和 hasOwnProperty 创建浅副本并将此副本存储在集合中。
- 为每个用户添加一个数据属性,该属性包含所有对象的属性,并且可以存储在集合中。
- 我写这篇文章时突然想到:我还可以将所有原型属性设置为不可枚举,这应该阻止它们存储在集合中。
但是,我确实有同样的问题:从集合加载用户时。 AFAIK 在 JavaScript 中创建对象原型后无法更改它。而且当 Mongo 实例化从集合中检索的对象时,也无法指定要使用的原型。所以基本上我总是使用 Mongo 获取从 Object 继承的对象。据我所知,从现在开始,我有两个选项来恢复可用的用户对象:
- 创建一个继承自 User 的新对象,并将结果对象上的每个属性复制到新创建的对象。 (兼容存储机制1和3)
- 创建一个继承自User的新对象,并将结果对象作为数据属性存储在新创建的对象上。 (兼容存储机制2)
我的假设,特别是关于为查询结果指定原型的可能性,是否正确?正确的做法是什么?为什么?我肯定不是第一个努力使用 Node.js 在 MongoDB 中存储和恢复对象的人。
目前我会采用 2/2 的方法。我不太喜欢它,但它是最高效的,也是唯一可以与 API 完美配合的。然而,我更愿意听到 API 实际上没有做错什么,但我这样做是因为不知道如何正确使用它。所以请赐教:)
I am currently playing around with node.js and MongoDB using the node-mongo-native driver.
I tested a bit around using the Mongo console storing and retrieving JS objects. I figured out, that if I store an object that contains functions/methods the methods and functions will also be stored in the collection. This is interesting since I thought that functions could not be stored in MongoDB (with the exception of the system.js collection, as suggested by the Mongo docs).
Also it will not only store the methods but actually each method and member of the object's entire prototype chain. Besides that I dont like this behaviour and think it's unintuitive I mustn't have it.
I was going to manage users in a Mongo collection. To do this I have a User object containing all of the users methods functioning as a prototype for each instance of an user. The user object itself would only contain the users attributes.
If I store a user in the Mongo collection I only want to store the own properties of the user object. No prototype members and especially no prototype methods. Currently I do not see how to cleanly do this. The options that I figured might work are:
- creating a shallow copy using foreach and hasOwnProperty and storing this copy in the collection.
- Add a data attribute to each user that contains all the object's attributes and can be stored in the collection.
- This just came to my mind writing this: I could also set all the prototypes properties to not enumerable which should prevent them from being stored in the collection.
However, I do have the same issues the other way around: when loading a user from a collection. AFAIK there is no way to change an objects prototype in JavaScript after it was created. And there's also no way to specify a prototype to use when Mongo instantiates objects it retrieved from a collection. So basically I always get objects that inherit from Object using Mongo. As far as I can tell I have 2 options to restore a usable user object from this point on:
- Create a fresh object inheriting from User and copying each attribute on the result object to the newly created object. (Compatible to storing mechanisms 1 & 3)
- Create a fresh object inheriting from User and storing the result object as a data attribute on the newly created object. (Compatible to storing mechanism 2)
Are my assumptions, especially about the possibility to specify a prototype for query results, correct? What's the right way to do it, and why? I'm surely not the first person struggling to store and resurrect objects in/from MongoDB using node.js.
Currently I would go with the approach 2/2. I don't really like it, but it is the most efficient and the only one that works cleanly with the API. However, I'd much rather hear that actually the API does nothing wrong, but I do for not knowing how to use it correctly. So please, enlighten me :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我最近才意识到,实际上可以更改 V8/node 中的对象原型。虽然这不在标准中,但在各种浏览器中都是可能的,尤其是在 V8/node 中!
这在各种模块和插件中都有使用——甚至核心模块也使用这种技术,尽管它不是 ECMAScript 标准。所以我想在node.js 中使用是安全的。
I just recently realized, that it actually is possible to change an objects prototype in V8/node. While this is not in the standard it is possible in various browsers and especially in V8/node!
This is used all over various modules and plugins - even core modules make use of this technique, allthough it is not ECMAScript standard. So I guess it is safe to use within node.js.
我不确定我是否准确地理解了你的问题...但是我想到了一件事:你检查过 Mongoose ORM 了吗? (http://mongoosejs.com/)
在定义模型和方法时,它为您提供了很多选项。特别是“虚拟”可能会令人感兴趣(http://mongoosejs.com/docs/virtuals.html)。
无论如何,希望它能帮助一些人!
I'm not sure I'm following you question exactly... but fwiw one thing came to mind: Have you checked out the Mongoose ORM? (http://mongoosejs.com/)
It gives you a lot of options when it comes to defining models and methods. In particular "Virtuals" might be of interest (http://mongoosejs.com/docs/virtuals.html).
Anyway, hope it helps some!