2013-06-21 5 views
11

정책에 대한 문서를 만들거나 업데이트하는 단일 메서드가 필요합니다. 검색하고 다른 기술을 시도 this one, 나는 내 문서에 대한 null _id와 함께 왔습니다. findByIdAndUpdate를 사용하면 비슷한 효과가 있습니다.몽구스 findOneAndUpdate Upsert _id null?

나는 컬렉션에 삽입 된 문서를 볼 수 있지만, _id 필드가 null :

exports.savePolicy = function (plcy, callback) { 
    console.log('priority is : ' + plcy.priority) 
    try { 
     var policy = new Policy(plcy); 
     var query = {_id: plcy._id}; //this may be null 
     var update = { 
      name: plcy.name || defaults.policyDefaults.name, 
      longDescription: plcy.longDescription || defaults.policyDefaults.longDescription, 
      shortDescription: plcy.shortDescription || defaults.policyDefaults.shortDescription, 
      priority: plcy.priority, colorHex: plcy.colorHex || defaults.policyDefaults.colorHex, 
      settings: plcy.settings || [], 
      parentPolicyId: plcy.parentPolicyId || null 
     } 

     Policy.findOneAndUpdate(query, update, {upsert: true}, function (err, data) { 
      callback(err, data); 
     }); 

    } catch (e) { 
     log.error('Exception while trying to save policy: ' + e.message); 
     callback(e, null); 
    } 

때이 아니 업데이 트 null이 될하지 않도록 _id을 얻기 위해 할 수있는 일이 있습니까?

+0

혹시이 알아낼 않았다? 나는이 같은 문제를 겪고 있었다. 결국 _id를 수동으로 확인한 다음 findOneAndUpdate를 호출하여 새 레코드를 만들거나 create()를 호출합니다. – Trent

답변

5

나는이 똑같은 문제를 안고 있었고 작동시킬 수있는 방법을 찾지 못했습니다. 내가 지금처럼 내 자신의 upsert 방법 .... 내가 한 줄의 코드 내 모델의 그것을 호출 할 수 있습니다

var upsert = function(model, data, f){ 
    if (!data._id) { 
    model.create(data, f); 
    } else { 
    var id = data._id; 
    delete data._id; 
    model.findOneAndUpdate({_id: id}, data, f); 
    } 
} 

를 ... 작성 결국

upsert(Team, team, f); 

가있을 수 있습니다 그것을하는 더 좋은 방법이지만, 이것은 나를 위해 일하고 있습니다. 업데이트 및 삽입 작업을 수행 할 수 있으며 삽입시 null _id가 표시되지 않습니다. 원하지 않는, 그래서 만약

+0

글쎄,이 문제를 해결하려면 다음과 같이하십시오 : Model.findOneAndUpdate ({_id : id || Mongoose.Types.ObjectId()}, {$ set : attrs}, {upsert : true, new : true}) –

11

null은 당신이 null 값으로 대체되어 있는지 확인해야합니다 새 문서에 사용하여 MongoDB에 유효한 _id 값 새로운 ObjectIDquery에 : 나는

var query = {_id: plcy._id}; 
if (!query._id) { 
    query._id = new mongoose.mongo.ObjectID(); 
} 

// the rest stays the same... 
+0

우리는 ObjectIds를 사용하여 생성 타임 스탬프를 추론합니다. ObjectIds가 클라이언트를 생성하는 대신 서버 측에서 생성되는 것이 가장 좋을까요? – dhaundy

1

Mongoose를 사용하지는 않지만 MongoDB와 비슷한 문제가 발생합니다. 새로운 객체가 삽입되었을 때 Upsert 동작을 위해 MongoDB는 null_id으로 설정하고있었습니다.

나는 호출되었습니다 obj._idundefined

findOneAndUpdate({my_id:'my_unique_id'}, obj, {upsert: true}) 

어디에.

_id은 키 목록 Object.keys(obj)에있었습니다. 나는 obj._id = some_variable을 할당하고 있는데, some_variableundefined이고 그 때문에 _id이 키 목록에 나타납니다.

내가 바로 upsert 전에 호출하여 해결 방법을 적용 :

if (_.isUndefined(obj._id)) { 
    delete obj._id; 
} 
0

감사를 JohnnyHK에 위의 도움이 대답.나는 그것이 너무 자주 사용 이후 한 - 라이너를 내놓았다 :

query = args._id ? { _id: args._id } : { _id: new ObjectId() }; 

그것은에 의존 필요 다음

const ObjectId = require('mongodb').ObjectID;