2013-08-29 3 views
3

http://mongoosejs.com/docs/populate.html에 따르면 개체를 가져올 때 ID가 아닌 개체에 ref 속성을 설정하면 ID가 아닌 개체를 가져와야합니다. 나는 페이지의이 부분을 말하는 겁니다 : 나는 t1.otherModel를 참조 할 때몽구스 참조가 ID로 변환되는 이유는 무엇입니까?

var T1schema = new mongoose.Schema({ 
    otherModel:{type:mongoose.Schema.Types.ObjectId, ref:"T2"} 
}); 

var T1 = mongoose.model('T1', T1schema); 

var T2schema = new mongoose.Schema({ 
    email: {type: String}, 
}); 

var T2 = mongoose.model('T2', T2schema); 

var t1 = new T1(); 
var t2 = new T2({email:"[email protected]"}); 
t1.otherModel = t2; 

지금, 그것은 단지 ObjectId가, 그리고이 아닌 T2 :

var guille = new Person({ name: 'Guillermo' }); 
guille.save(function (err) { 
    if (err) return handleError(err); 

    story._creator = guille; 
    console.log(story._creator.name); 
    // prints "Guillermo" in mongoose >= 3.6 
    // see https://github.com/LearnBoost/mongoose/wiki/3.6-release-notes 

여기 내 예제 코드입니다. 예 :

console.log(t1.otherModel.email); 

"[email protected]"대신 undefined가 인쇄됩니다. 어떤 아이디어? 참고 package.json에 따라 Mongoose 3.6.18을 사용하고 있습니다.

감사합니다.

답변

2

나는 당신의 기대가 단지 몽구스가하는 것과 일치하지 않는다고 생각합니다. 스키마는 "모델 M의 특성 P는 항상 유형 T가 될 것입니다"라고 말하는 방식입니다. 따라서 값을 설정할 때 mongoose는 스키마 정의를 사용하여 스키마에 필요한 유형으로 설정 값을 변환합니다. 여기에 약간의 REPL 세션이 있습니다. 문자열 값으로 숫자 속성을 설정하면 숫자로 변환되지만 숫자 필드에 부울 값을 저장하려고하면 잘못된 값은 무시됩니다. 스키마는 무언가가 당신이 그것을 모델 인스턴스를 줄 경우, ObjectId가 될 것입니다 말할 때

> var mongoose = require('mongoose') 
> var schema = new mongoose.Schema({prop1: Number}) 
> var Model = mongoose.model('Model', schema) 
> var m = new Model 
> m.prop1 = 42 
42 
> m.prop1 
42 
> m.prop1 = "42" 
'42' 
> m.prop1 
42 
> m.prop1 = false 
false 
> m.prop1 
42 

그래서, 몽구스는 바로 일반적인 경우입니다 데이터베이스에 쓰기위한 준비에 ObjectId가로 변환합니다. 일반적으로 모델 인스턴스를 설정 한 경우 상위 모델을 데이터베이스로 저장하기 전에 상위 모델에서 다시 가져올 필요가 없습니다.

따라서 모델 인스턴스 게터 정의 속성은 항상 스키마와 호환되는 것을 반환하고 populate은 DB에서 참조를로드하는 것과 관련이 있습니다. 그러나 어떤 이유로 든 몽구스는 동일하지 않습니다. .populate d 인스턴스가 채워지지 않은 인스턴스. 나는 이것이 왜 혼란스럽고 예기치 못한/실망 스러운지를 알 수 있습니다.

+0

감사합니다. 문서에서는 ref를 업데이트하면 id가 저장되지만 getter는 객체를 반환합니다. 개체를 저장 한 후에 만 ​​작동한다는 것은 이상한 것 같습니다. – tkrein

+0

Mongoose는 동기식 ref 할당 작업을 수행하지 않고 DB 쿼리를 만들어 개체를 가져 와서 메모리에 저장합니다. 어쨌든 콜백이 없습니다. 그것은 id를 모델로 변환하기 위해해야 ​​할 일이고 mongoose는 비동기 함수 중 하나를 호출 할 때 DB IO 만 수행합니다. –

+0

예제에서 데이터베이스가 전혀 개입되지 않았습니다. 나는 세트를 기대하고있다/재귀 될 수 있습니다. 객체가있는 ref 속성에 set을 호출하면 get이 방금 설정 한 값을 반환 할 것으로 예상합니다. 몽구스 문서에 따르면, 이것이 예상되는 행동입니다 (제가 인용 한 섹션에서).예제와 그 유일한 차이점은 DB에서로드 된 객체로 작업하고 있으며, 내 객체가 새로운 객체로 작업하고 있다는 것입니다. 특히 그들은 set _creator = guille을 호출하고 호출하는 다음 행은 _creator를 가져오고 ID가 아닌 객체를 가져옵니다. – tkrein

0

몽구스가 Schema과 일치하도록 인스턴스를 정규화합니다. otherModelObjectId입니다.

otherModel:{type:mongoose.Schema.Types.ObjectId, ref:"T2"} 

그래서, 몽구스는 t1.otherModel = t2; 취급 동일하게 다음 ref는에 오브젝트를 모두 필요로하는 (직접 쿼리 문서에 또는 중 하나)라고 .populate() 때까지 사용하지

t1.otherModel = t2._id; 

저장해야합니다 :

t2.save(function (err) { 
    t1.save(function (err) { 
     console.log(t1.otherModel); 
     // 7890ABCD... 

     t1.populate('otherModel', function() { 
      console.log(t1.otherModel); 
      // { email: '[email protected]', _id: 7890ABCD..., __v: 0 } 
     }); 
    }); 
}); 
+0

그러나 몽구스는 t1.otherModel = t2를 치료하지 않습니다. t1.otherModel = t2._id; 내 의견으로는 일관성없는 행동 인 채우기 호출 후 그 (것)들을 동일한 전후 우편물 또는 대우하지 말라. – tkrein

관련 문제