2014-02-15 2 views
4

문서가 없으면 추가하고 그 중 하나에 하위 문서를 추가하고 싶습니다. Peter이있는 경우MongoDB setOnInsert 및 push (이미 존재하는 경우)

db.test.update(
    { 
    name : 'Peter' 
    }, 
    $setOnInsert : { 
     name : 'Peter', 
     visits: { 'en' : ['today'], 'us' : [] } 
    }, 
    $push : { 
     visits.en : 'today' 
    }, 
    { upsert : true } 
) 

는 그 visists.en 또는 visists.us 배열에 요소를 추가 할 수 있습니다. 그렇지 않으면 Peter에 대한 문서를 만듭니다. 이 문서는 현재 요소 ('today')를 포함해야하는 visits의 형식이어야합니다.

내 문제는 내가 "have conflicting mods in update"입니다. 즉, (afaik), 나는 하나의 쿼리에서 두 가지를 쓸 수 없다. 그러나이 딜레마를 어떻게 해결할 수 있습니까?

답변

5

$setOnInsert 연산자없이 구현할 수 있습니다.

db.test.update(
    { 
    name : 'Peter' 
    }, 
    { 
    $push : { 
     "visits.en" : 'today' 
    } 
    }, 
    { upsert : true } 
) 

베드로가 존재하는 경우

는 요소 'today'visits.en 배열에 추가됩니다. 그렇지 않으면 visits 개체와 함께 Peter의 문서가 만들어지며 배열 en'today' 요소가 포함됩니다.
두 작업 ( $setOnInsert$push)에서 동일한 속성 ( visits)을 사용하기 때문에 오류가 발생했다고 생각합니다. 당신은 여전히 ​​ $setOnInsert을 사용할 수 있습니다

+1

Sweet, 나는 기존 필드가 아닌 '$ push'할 수 있다는 것을 몰랐습니다. 이것은 나의 문제를 해결합니다. 내 쿼리를 조금 단순화했기 때문에'$ setOnInsert'를 고수해야합니다. 대신 나는'$ setOnInsert'에서'visit : { 'en': [ 'today'], 'us': []}'를 제거 할 것입니다. – Marius

0

하지만, 이전에 언급 한 바와 같이 $setOnInsert$push 같은 필드에없는 업데이트를 수행 할 때.

주의 : 당신이

Node.js를에서
db.test.update(
    { 
     name : 'Peter' 
    }, 
    { 
     $setOnInsert: {name : 'Peter'}, 
     $addToSet: {"visits.en": 'today'} // or $push 
    }, 
    {upsert: true}) 

이 배열에서 중복 값을 원하지 않는 경우 우리는 $addToSet를 사용 : 나는 이런 식으로 일을 오전을하지만 당신은 여전히 ​​쿼리를 사용할 수 있습니다 직접.

내 이유는 잘못된 필드 이름으로 레코드를 업데이트하고 업데이트 쿼리를 구성하지 않기 때문입니다.

먼저 스키마의 인스턴스를 만들어야합니다. 이 스키마 기본적으로 생성 된 _id 속성에 대해 인스턴스를 생성하고 독특한, 그래서 우리는 $setOnInsert 기능 오른쪽 있도록 인스턴스에서 제거해야 할 때

var testSchema = require(./path/testSchema.js); // require your schema 
var test = conn.model("test", testSchema, "test"); //conn is the mongoose connection object to the DB 
var testToCreate = new test(); 
testToCreate.name : 'Peter' //add fields to the instance 

    var testToUpsert = testToCreate.toObject(); 
    delete testToUpsert._id; 
    delete testToUpsert.visits; 

둘째, 우리는하지의 방문 배열을 제거 $setOnInsert과 함께 $addToSet (또는 $push)을 사용할 때 동일한 필드에 영향을주는 2 개의 쿼리가 있습니다.

var options = { 
    upsert: true 
    }; 

    test.update({ 
     name : 'Peter' 
    }, { 
     $setOnInsert: testToUpsert, 
     $addToSet: { 
     "visits.en":'today' 
     } 
    }, 
    options, 
    function(err, testAffected) { 
     if (err) { 
     return console.error(err); 
     } 
     console.log('testAffected! :', testAffected); 
    });