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
'programing' 카테고리의 다른 글
jq를 사용하여 내부 배열의 값을 기준으로 개체 배열을 필터링하려면 어떻게 해야 합니까? (0) | 2023.03.27 |
---|---|
Mongoose에서 .populate()로 특정 필드를 반환합니다. (0) | 2023.03.27 |
각도 js 알 수 없는 공급자 (0) | 2023.03.27 |
금지 /wp-login에 액세스할 수 있는 권한이 없습니다.이 서버의 php (0) | 2023.03.27 |
WordPress는 HTML 페이지를 어디에 저장합니까? (0) | 2023.03.27 |