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);

また、最初の出力 (インストール) はプロパティ「モード」を含む素敵なオブジェクトですが、2 番目の出力は未定義です。

何を与える?

4

1 に答える 1

6

最後に、私はこれを解決しました...

console.log(typeof user.installations[i]); を実行してみました。出力として「string」を取得しました。オブジェクトを直接印刷すると、文字列ではなく通常のオブジェクトのように見えるコンソール出力 (上記) が作成されたことを考えると、これは奇妙に思えました。それで、私は 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 パーサーは、JSON 文字列 (上記) の最初のキーである「runs」の最初の文字である文字「r」で失敗していることに注意してください。最初は、カスタム JSON パーサーを入手する必要があるのではないかと心配していましたが、問題が発生しました。

元のスキーマを振り返ってください。配列フィールドはインストールの _id プロパティを文字列として格納していたため、文字列型を使用してインストール ref を定義しました。.populate() フィールドは、出力時にオブジェクトを文字列に変換していると思います。

最後に、Mongoose のドキュメントをもう少し詳しく見て、Schema.ObjectID に基づいてオブジェクトを参照することになっていることに気付きました。これですべてが説明されますが、スキーマとコードを他の場所で修正する必要があることは確かです...

于 2012-07-28T07:07:35.753 に答える