programing

MongoDB 문서 필드가 존재하지 않는 경우에만 업데이트하려면 어떻게 해야 합니까?

abcjava 2023. 3. 27. 20:52
반응형

MongoDB 문서 필드가 존재하지 않는 경우에만 업데이트하려면 어떻게 해야 합니까?

나는 수집이 있다.foo다음과 같은 문서를 사용합니다.

{site_id: 'xxx', title: {ru: 'a', en: 'b'}, content: {ru: 'a', en: 'b'}}
{site_id: 'xxx', title: {ru: 'c', de: 'd'}, content: {ru: 'c', de: 'd'}}

존재 가능 또는 존재하지 않는 여러 필드를 업데이트해야 합니다.

db.foo.update(
    { site_id: 'xxx'},
    { $set: {'title.de': '', 'content.de': ''}},
    {multi: true}
)

하지만 난 이런 게 필요해$set값이 존재하는 경우 값을 덮어쓰지 않습니다.

업데이트 문에 쿼리를 추가할 수 있습니다.

db.foo.update({'title.de': {$exists : false}}, {$set: {'title.de': ''}})

갱신하다

수정한 질문의 경우, 제 솔루션은 다음과 같습니다.그렇게 하면 될까요? (그렇지 않다면 왜일까요?)

db.foo.update({site_id: 'xxx', 'title.de': {$exists : false}}, {$set: {'title.de': ''}, {multi: true})
db.foo.update({site_id: 'xxx', 'content.de': {$exists : false}}, {$set: {'content.de': ''}}, {multi: true})

시작하는Mongo 4.2는 집약 파이프라인을 받아들일 수 있으며, 최종적으로 다른 필드를 기반으로 한 필드의 갱신 또는 갱신을 허용합니다.

이렇게 하면 일치 단계가 아닌 업데이트 단계 내에서 필드 체크를 이동할 수 있으므로 원패스 업데이트가 됩니다.

// { site_id: "xxx", title: { ru: "a", en: "b" }, content: {} }
// { site_id: "xxx", title: { ru: "c", de: "d" }, content: { ru: "c" } }
db.collection.updateMany(
  { site_id: "xxx" },
  [{ $set: {
    "title.de": { $cond: [ { $not: ["$title.de"] }, "", "$title.de" ] },
    "content.ru": { $cond: [ { $not: ["$content.ru"] }, "", "$content.ru" ] }
  }}]
)
// { site_id: "xxx", title: { ru: "a", en: "b", de: "" }, content: { ru: "" } }
// { site_id: "xxx", title: { ru: "c", de: "d"         }, content: { ru: "c" } }
  • 첫 번째 부분{ site_id: "xxx" }는 갱신할 문서를 필터링하는 일치 쿼리입니다.

  • 두 번째 부분[{ $set: { ... } }]는 업데이트 집약 파이프라인입니다(집약 파이프라인 사용을 나타내는 각 괄호 참조).$set 는 새로운 집약 연산자이며 에일리어스입니다$addFields이 스테이지의 나머지 부분은$cond만약title.de존재하는 경우, 그대로 유지하거나, 그렇지 않은 경우 로서 작성하십시오.''.

업데이트 필드 연산자 $setOn이 있습니다.요건을 충족하는 삽입.다음 문서를 참조하십시오.https://docs.mongodb.com/manual/reference/operator/update/setOnInsert/ #up . _ S _ set On Insert .

한 가지 특정 사례에 대한 해결책이 있지만, 누군가 도움이 될 수도 있습니다.

몇 개의 필드를 갱신해 주세요.그 중 한 번만 갱신해야 하는 필드가 있었습니다(「Date_of_first_update」라고 부릅니다).

> db.test.find();
{ "_id" : ObjectId("57f298fdeb30478a033c70e4"), "a" : "1", "b" : "2" }

First update:

> db.test.updateOne({ "_id" : ObjectId("57f298fdeb30478a033c70e4")}, 
  {$set: {a: 100, b: 200 }, $min : {'Date_of_first_update' : (new Date())  }});

Result: 'a', 'b' updated, 'Date_of_first_update' is set.

{ "_id" : ObjectId("57f298fdeb30478a033c70e4"), "a" : 100, "b" : 200, "Date_of_first_update" : ISODate("2016-10-03T**17:47:43**.570Z") }

Second update:

> db.test.updateOne({ "_id" : ObjectId("57f298fdeb30478a033c70e4")}, 
  {$set: {a: 400, b: 800 }, $min : {'Date_of_first_update' : (new Date()) }});

Result: 'a', 'b' updated, 'Date_of_first_update' left unchanged, as I needed!!!

{ "_id" : ObjectId("57f298fdeb30478a033c70e4"), "a" : 400, "b" : 800, "Date_of_first_update" : ISODate("2016-10-03T**17:47:43**.570Z") } 

나처럼 문제가 발생한 경우:

이 솔루션은 업데이트로 인해 새 버전이 삽입된 경우에만 _id를 설정하는 것입니다( ).upsert: true)

return {
    updateOne: {
        filter: {
            email: shadowUser.email,
        },
        update: {
            $set: user,
            $setOnInsert: { _id: shadowUser._id },
        },
        upsert: true,
    },
};

이 답변은 기본적으로 접근방식의 개요를 제시하지만 MongoDB 2.6 이후에서는 "대량 업데이트"를 지원하는 구현으로 인해 이러한 작업을 수행할 수 있습니다.

이는 여전히 "원자적으로" 별개의 업데이트 문입니다.하지만 한 번에 "전화를 통해" 제출할 수 있습니다.이를 통해 적어도 업데이트 간의 지연이 서버에서 실행될 때 훨씬 짧아집니다.

var bulk = db.foo.initializeBulkOrderedOp();
bulk.find({ "site_id": "xxx",
    "title.de": { "$exists" false } })
    .update({ "$set": { "title.de": "" } });
bulk.find({ "site_id": "xxx", 
    "content.de": { "$exists" false } })
    .update({ "$set": { "content.de": "" } });
bulk.execute();

즉, 실제로는 서버로의 왕복 1회입니다.모든 것이 전송되기 때문입니다..execute()

그러나 현재의 폼에서는(이것은 데이터의 정확한 표현은 아닐 수 있지만), 실제로는 이것을 1회의 조작으로 실시하기 위해서 「구조 변경」을 실시할 수 있습니다.따라서 문서가 다음과 같은 경우:

{ 
    "site_id": "xxx",
    "docs": [
        { "title": "a", "content": "a", "lang": "ru" },
        { "title": "b", "content": "b", "lang": "en" }
    ]
},
{
    "site_id": "xxx",
    "docs": [
        { "title": "c", "content": "c", "lang": "ru" },
        { "title": "d", "content": "d", "lang": "de" }
    ]
}

다음으로, 「set」요소가 「unique」가 되는 경우의 룰에 따라, 다음과 같이 동작합니다.

db.foo.update(
    { "site_id": "xxx" },
    { "$addToSet": { "docs": { "title": "d", content: "d", "lang": "de" } } },
    { "multi": true }
)

또는 논리 없이 존재 여부만 확인하는 경우에도 마찬가지입니다.

db.foo.update(
    { "site_id": "xxx", "docs.lang": { "$ne": "de" } },
    { "$push": { "docs": { "title": "", "content": "", "lang": "de" } } },
    { "multi": true }

)

마지막 경우 다음과 같은 결과가 초래됩니다.

{
    "_id" : ObjectId("53c936265117367f5ff2038b"),
    "site_id" : "xxx",
    "docs" : [
            {
                    "title" : "a",
                    "content" : "a",
                    "lang" : "ru"
            },
            {
                    "title" : "b",
                    "content" : "b",
                    "lang" : "en"
            },
            {
                    "title" : "",
                    "content" : "",
                    "lang" : "de"
            }
    ]
}
{
    "_id" : ObjectId("53c936265117367f5ff2038c"),
    "site_id" : "xxx",
    "docs" : [
            {
                    "title" : "c",
                    "content" : "c",
                    "lang" : "ru"
            },
            {
                    "title" : "d",
                    "content" : "d",
                    "lang" : "de"
            }
    ]
}

따라서 다른 방법으로 작업을 "처리"하거나 스키마를 변경하여 원하는 업데이트를 자동으로 수행할 수 있습니다.

@nutlike의 답변으로 문제가 해결되기는 하지만 아이템의 여러 필드를 업데이트하려면 많은 데이터베이스 작업이 필요합니다.요컨대, 당신이 원하는 것은 정확히 가능하지 않다.

문서가 한 번에 수행하는 업데이트 수보다 많은 업데이트(2개 이상의 IMO)를 수행할 경우 문서를 가져와 필드를 업데이트한 후 저장해야 합니다.이것은 루트를 작성/업데이트하는 몇 가지 OAuth 사용자에 대해 수행하는 작업입니다.

~로update.updateOne ★★★★★★★★★★★★★★★★★」updateMany당신의 요구에 따라.

updateMany한 번에 업데이트 할 수 있습니다.

db.foo.updateMany({'title.de': {$exists : false}}, {$set: {'title.de': ''}})

// 하지 않는 서는 // 를 추가하는 것을 . 기서 、 란란란lob: 'Marine'lob모든 문서에는 필드가 없습니다.

db.collections.updateMany({'lob': { $exists: false }}, { $set: { lob: 'Marine'}}); 

언급URL : https://stackoverflow.com/questions/24824657/how-do-i-update-mongodb-document-fields-only-if-they-dont-exist

반응형