无法从 Mongoose 访问 populate()'d 对象的属性?

Posted

技术标签:

【中文标题】无法从 Mongoose 访问 populate()\'d 对象的属性?【英文标题】:Cannot access properties on a populate()'d object from Mongoose?无法从 Mongoose 访问 populate()'d 对象的属性? 【发布时间】:2012-07-26 16:11:27 【问题描述】:

这很奇怪...我正在使用带有 ref 的 populate() 来填充我的架构中的一个数组,但是这些属性是不可访问的。换句话说,架构是这样的:

new Model('User',
    'name': String,
    'installations': [ type: String, ref: 'Installations' ],
    'count': Number,

当然,Insallations 是另一种模式。

然后我找到并填充一组用户...

model.find(count: 0).populate('installations').exec( function(e, d)
    for(var k in d)
     
        var user = d[k];
        for(var i in user.installations)
        
            console.log(user.installations[i]);
        
    
 );

到目前为止一切顺利!我看到打印出来的数据不错,如下所示:

 runs: 49,
hardware: 'macbookpro10,1/x86_64',
mode: 'debug',
version: '0.1' 

但是,如果我尝试实际访问这些属性中的任何一个,它们都是未定义的!例如,如果我添加另一个控制台日志:

console.log(user.installations[i].mode);

然后我看到此日志打印了“未定义”。 如果我尝试对对象进行操作,像这样:

 Object.keys(user.installations[i]).forEach(function(key)   );

然后我得到一个典型的“[TypeError: Object.keys called on non-object]”错误,表明 user.installations[i] 不是对象(即使它被输出到控制台就好像它是一样) .所以,我什至尝试了一些丑陋的东西,比如......

var install = JSON.parse(JSON.stringify(user.installations[i]));
console.log(install, install.mode);

同样,第一个输出(安装)是一个不错的对象,包含属性“模式”...但第二个输出未定义。

什么给了?

【问题讨论】:

【参考方案1】:

最后,我解决了这个问题...

我尝试做一个 console.log(typeof user.installations[i]);并得到“字符串”作为输出。这看起来很奇怪,因为直接打印对象会创建看起来像普通对象而不是字符串的控制台输出(上图)。所以,我试着做一个 JSON.parse();在对象上,但收到错误“SyntaxError: Unexpected token r”

终于,我意识到发生了什么事。我上面描述的“漂亮的控制台输出”是用 \n (换行符)格式化的字符串的结果。无论出于何种原因,我都没有预料到这一点。 JSON.parse() 错误是由于 node.js 解析器在尝试解析不带引号的对象键时存在已知的必要性;在此处查看 SO 问题: Why does JSON.parse('"key" : "value"') do just fine but JSON.parse('key : "value"') doesn't? 。

请注意,在我的案例中,JSON 解析器在字符“r”上失败,“r”是“runs”的第一个字符,这是我的 JSON 字符串中的第一个键(上图)。起初我担心我需要一个自定义的 JSON 解析器,但后来我遇到了问题。

回头看看我原来的架构。我使用字符串类型来定义安装引用,因为数组字段将安装的 _id 属性存储为字符串。我假设 .populate() 字段正在将对象转换为输出字符串。

最后,我仔细查看了 Mongoose 文档,并意识到我应该基于 Schema.ObjectID 引用对象。这解释了一切,但肯定让我在我的架构和其他地方的代码中做一些修复......

【讨论】:

也 .toJSON() 可用于转换为对象,并在您使用 strict:false 即无模式架构时提供帮助 如果我记录填充的数据,我会看到我期望看到的。但是,如果我尝试使用点访问某些字段,则会抛出错误“xxxx 不存在于类型‘字符串’上”经过差不多几年后,您的解释仍然有效。

以上是关于无法从 Mongoose 访问 populate()'d 对象的属性?的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB和Mongoose:无法使用.populate()填充用户的帖子

Mongoose中关联查询populate的使用

Mongoose populate() 返回空数组

mongoose.populate() 未显示填充内容

mongoose.populate() 未显示填充内容

Mongoose .populate 随机