水线MongoDb(填充)获取对象丢失其类型和原型函数 [英] Waterline MongoDb (populated) fetched object looses its type AND prototype functions

查看:203
本文介绍了水线MongoDb(填充)获取对象丢失其类型和原型函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用mongo db在水线以上的帆。



假设我在我的帆项目中声明了2个模型:



用户模型@ models / User.js simplified:

 用户名:{
type:'string',
unique:true
},
护照:{
集合:'Passport',
via:'owner'
},

aUserFunction:function(){
console.log ');
}

和护照模型@ models / Passport.js simplified:

 密码:{
type:'string'
} ,

owner:{
model:'User',
required:true
},

aPassportFunction:function b $ b console.log('I'm a passport function');
}

到目前为止很好。

当我提取其中一个关联对象时,我这样做:

  .models.user 
.findOne({username:'aUsername'})
.populate('passports')// populate方法允许获取关联数据
.exec err,myUser){
...
JSON.stringify(myUser); //对象返回很好
...
}
myUser
对象是:

$ b


$ b

  {
用户名:aUsername,
护照:
[
{
:'aPass',
owner:'theUsersId'
}
]
}

$ b b

我现在可以按预期运行 myUser.aUserFunction(); ,因为 myUser models / User.js



如果我试图在特定护照上this:
var passport = myUser.passports [0];





尝试运行 passport.aPassportFunction(); 是不可能的,因为返回的对象是类型对象而不是模型/ Passport.js



现在从我所知道的类型在JavaScript中的类型转换,这将是一个美好的时间使用它。



我不想复制粘贴值一个新的对象,为了使用 aPassportFunction(),它似乎浪费了资源。



是否有其他方式投放此通用护照对象模型/护照。 js 类型。

解决方案

mongodb实际上不应该存储除数据之外的任何东西,函数:



使用Node.js在Mongo DB中存储JS函数的问题



但是 myUser.aUserFunction 工作,我相信,是因为水线的findOne实际上将对象转换为水线对象,而不是实际存储在mongodb。 Mongodb将只返回一个平面文件。如果你做一个mongodb查询,你会发现你的填充关联甚至不存在于父对象下。



所以你被限制在什么水线允许你做。



一个建议是不使用水线一对多关联,而是使用mongodb一对多关联:



myuser.js:

  {
用户名:aUsername,
护照:
[
ObjectId(passportid),
ObjectId(passportid)
]
}
pre>

然后你就可以在护照对象id上利用水线的findOne,并获得Passport.js对象,而不是只有Passport数据嵌入的User.js对象。



详情:
https://www.safaribooksonline.com/blog/2012/12/18/document-oriented-data-modeling-with-mongodb/


I'm using sails with mongo db over waterline.

Lets say that I declare 2 models in my sails project like so :

A user model @ models/User.js simplified:

username: {
        type: 'string',
        unique: true
 },
passports: {
        collection: 'Passport',
        via: 'owner'
},

aUserFunction: function(){       
    console.log('I'm a user function');
}

and a passport model @ models/Passport.js simplified:

password: {
      type: 'string'
 },

owner: {
      model: 'User',
      required: true
 },

aPassportFunction: function(){
    console.log('I'm a passport function');
}

So far so good.

When I fetch one of those associated objects I do it like so:

sails.models.user
.findOne({ username: 'aUsername' })
.populate('passports') // The populate method allows you to get associated data
.exec(function (err, myUser) {
    ...
    JSON.stringify(myUser);   //The object returns just fine!
    ...
}

As expected the returned myUser object is this:

{
    username:"aUsername",
    passports: 
    [
        {
            password: 'aPass',
            owner: 'theUsersId'
        }
    ]            
}

I can now run myUser.aUserFunction(); as expected, since myUser is of type models/User.js.

If I try to get my hands on the specific passport I can do this: var passport = myUser.passports[0];

The problem:

Trying to run passport.aPassportFunction(); is impossible, since the returned object is of type Object and not models/Passport.js.

Now from what I know theres NO type casting in javascript, and that would be a wonderful time to use it.

I wouldn't like to copy paste the values into a new object in order to use the aPassportFunction(), it seems like a waste of resources.

Is there any other way to cast this generic passport Object as models/Passport.js type.

解决方案

mongodb actually should not store anything besides data, and so it shouldnt store any functions:

Problems storing JS functions in Mongo DB with Node.js

But the reason why myUser.aUserFunction() works, i believe, is because waterline's findOne actually transforms the object into the waterline object, not what is actually stored in mongodb. Mongodb will only return you a flat file. If you do a mongodb query you will find that your populated association doesn't even exist under the parent object.

So you are limited to what waterline allows you to do.

One suggestion is instead of using the waterline one-to-many association, make a mongodb one-to-many association instead:

myuser.js:

{
  username:"aUsername",
  passports: 
    [
      ObjectId("passportid"),
      ObjectId("passportid")
    ]            
}

Then you will be able to leverage waterline's findOne on the passport object id and get the Passport.js object, instead of a User.js object with only Passport's data embedded.

Details: https://www.safaribooksonline.com/blog/2012/12/18/document-oriented-data-modeling-with-mongodb/

这篇关于水线MongoDb(填充)获取对象丢失其类型和原型函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆