5

这很奇怪......我正在使用带有 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);

而且,第一个输出(安装)是一个很好的对象,包含属性“模式”......但第二个输出是未定义的。

是什么赋予了?

4

1 回答 1

6

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

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

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

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

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

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

于 2012-07-28T07:07:35.753 回答