Docs Menu

db.collection.findAndModify()

๋“œ๋ผ์ด๋ฒ„๊ฐ€ ํฌํ•จ๋œ MongoDB

์ด ํŽ˜์ด์ง€์—์„œ๋Š” mongosh ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. MongoDB ๋“œ๋ผ์ด๋ฒ„์—์„œ ๋™์ผํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ๋ณด๋ ค๋ฉด ํ•ด๋‹น ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์˜ ํ•ด๋‹น ํŽ˜์ด์ง€๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

db.collection.findAndModify(document)

์ค‘์š”

๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” mongosh ๋ฉ”์„œ๋“œ

๋Œ€์‹  findOneAndUpdate(), findOneAndDelete() ๋˜๋Š” findOneAndReplace()์„(๋ฅผ) ์‚ฌ์šฉํ•˜์„ธ์š”.

๋‹จ์ผ ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๋œ ๋ฌธ์„œ์—๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ ์‹œ ์ˆ˜์ •๋œ ๋‚ด์šฉ์ด ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ์— ๋Œ€ํ•œ ์ˆ˜์ • ์‚ฌํ•ญ์ด ์žˆ๋Š” ๋ฌธ์„œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ ค๋ฉด new ์˜ต์…˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ํ™˜๊ฒฝ์—์„œ ํ˜ธ์ŠคํŒ…๋˜๋Š” ๋ฐฐํฌ์— db.collection.findAndModify() ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • MongoDB Atlas: ํด๋ผ์šฐ๋“œ์—์„œ์˜ MongoDB ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ ์™„์ „ ๊ด€๋ฆฌํ˜• ์„œ๋น„์Šค

  • MongoDB Enterprise: MongoDB์˜ ๊ตฌ๋… ๊ธฐ๋ฐ˜ ์ž์ฒด ๊ด€๋ฆฌ ๋ฒ„์ „

  • MongoDB Community: MongoDB์˜ ์†Œ์Šค ์‚ฌ์šฉ ๊ฐ€๋Šฅ ๋ฌด๋ฃŒ ์ž์ฒด ๊ด€๋ฆฌ ๋ฒ„์ „

๋ฒ„์ „ 5.0์—์„œ ๋ณ€๊ฒฝ๋จ

findAndModify() ๋ฉ”์„œ๋“œ์˜ ํ˜•์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

db.collection.findAndModify({
query: <document>,
sort: <document>,
remove: <boolean>,
update: <document or aggregation pipeline>,
new: <boolean>,
fields: <document>,
upsert: <boolean>,
bypassDocumentValidation: <boolean>,
writeConcern: <document>,
maxTimeMS: <integer>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
let: <document> // Added in MongoDB 5.0
});

db.collection.findAndModify() ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ์˜ ๋‚ด์žฅ๋œ ๋ฌธ์„œ ํ•„๋“œ๋กœ ๋ฌธ์„œ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Parameter
์œ ํ˜•
์„ค๋ช…

query

๋ฌธ์„œ

์„ ํƒ ์‚ฌํ•ญ. ์ˆ˜์ •์„ ์œ„ํ•œ ์„ ํƒ ๊ธฐ์ค€์ž…๋‹ˆ๋‹ค. ํ•„๋“œ query ๋ฉ”์„œ๋“œ์—์„œ db.collection.find() ์‚ฌ์šฉ๋œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ์ฟผ๋ฆฌ ์„ ํƒ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ฟผ๋ฆฌ ์—ฌ๋Ÿฌ ๋ฌธ์„œ์™€ ์ผ์น˜ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋Š”db.collection.findAndModify() ์ˆ˜์ •ํ•  ๋ฌธ์„œ ํ•˜๋‚˜๋งŒ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๋นˆ ๋ฌธ์„œ๋กœ ๊ธฐ๋ณธ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

์ฟผ๋ฆฌ ์ธ์ˆ˜๊ฐ€ ๋ฌธ์„œ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์ž‘์—… ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

sort

๋ฌธ์„œ

์„ ํƒ ์‚ฌํ•ญ. ์ฟผ๋ฆฌ ์—ฌ๋Ÿฌ ๋ฌธ์„œ๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒฝ์šฐ ์ž‘์—…์„ ์—…๋ฐ์ดํŠธํ•  ๋ฌธ์„œ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. db.collection.findAndModify() ๋Š” ์ด ์ธ์ˆ˜๋กœ ์ง€์ •๋œ ์ •๋ ฌ ์ˆœ์„œ์— ๋”ฐ๋ผ ์ฒซ ๋ฒˆ์งธ ๋ฌธ์„œ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

์ •๋ ฌ ์ธ์ˆ˜๊ฐ€ ๋ฌธ์„œ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์ž‘์—… ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

MongoDB๋Š” ํŠน์ • ์ˆœ์„œ์— ๋”ฐ๋ผ ๋ฌธ์„œ๋ฅผ ์ปฌ๋ ‰์…˜์— ์ €์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ค‘๋ณต ๊ฐ’์ด ํฌํ•จ๋œ ํ•„๋“œ๋ฅผ ์ •๋ ฌํ•  ๋•Œ ํ•ด๋‹น ๊ฐ’์ด ํฌํ•จ๋œ ๋ฌธ์„œ๋Š” ์ž„์˜์˜ ์ˆœ์„œ๋กœ ๋ฐ˜ํ™˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๊ด€์ ์ธ ์ •๋ ฌ ์ˆœ์„œ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๊ณ ์œ ๊ฐ’์ด ํฌํ•จ๋œ ํ•„๋“œ๋ฅผ ์ •๋ ฌ์— ํ•˜๋‚˜ ์ด์ƒ ํฌํ•จํ•˜์„ธ์š”. ์ด๋ฅผ ๋ณด์žฅํ•˜๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ ์ •๋ ฌ ์ฟผ๋ฆฌ์— _id ํ•„๋“œ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€ Sort Consistency(์ •๋ ฌ ์ผ๊ด€์„ฑ)์„(๋ฅผ) ์ฐธ์กฐํ•˜์„ธ์š”.

remove

๋ถ€์šธ

remove ๋˜๋Š” update ํ•„๋“œ ์ค‘ 1๊ฐœ๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. query ํ•„๋“œ์— ์ง€์ •๋œ ๋ฌธ์„œ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒ๋œ ๋ฌธ์„œ๋ฅผ ์ œ๊ฑฐํ•˜๋ ค๋ฉด ์ด ๊ฐ’์„ true(์œผ)๋กœ ์„ค์ •ํ•˜์„ธ์š”. ๊ธฐ๋ณธ๊ฐ’์€ false์ž…๋‹ˆ๋‹ค.

update

๋ฌธ์„œ ๋˜๋Š” ๋ฐฐ์—ด

remove ๋˜๋Š” update ํ•„๋“œ ์ค‘ 1๊ฐœ๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒ๋œ ๋ฌธ์„œ์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

new

๋ถ€์šธ

์„ ํƒ ์‚ฌํ•ญ. true ์ธ ๊ฒฝ์šฐ ์›๋ณธ์ด ์•„๋‹Œ ์—…๋ฐ์ดํŠธ๋œ ๋ฌธ์„œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ false ์ž…๋‹ˆ๋‹ค.

fields

๋ฌธ์„œ

์„ ํƒ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜ํ•  ํ•„๋“œ์˜ ํ•˜์œ„ ์„ธํŠธ์ž…๋‹ˆ๋‹ค. fields ๋ฌธ์„œ๋Š” fields: { <field1>: 1, <field2>: 1, ... }๋Œ€๋กœ ๊ฐ’์ด 1์ธ ํ•„๋“œ๋ฅผ ํฌํ•จํ•˜๋„๋ก ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

fields ์ธ์ˆ˜๊ฐ€ ๋ฌธ์„œ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์ž‘์—… ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

fields ํ”„๋กœ์ ์…˜ ์— ๋Œ€ํ•œ์ž์„ธํ•œ ๋‚ด์šฉ์€ ํ”„๋กœ์ ์…˜์„ ์ฐธ์กฐํ•˜์„ธ์š”.

upsert

๋ถ€์šธ

์„ ํƒ ์‚ฌํ•ญ. update ํ•„๋“œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

truefindAndModify() ์ธ ๊ฒฝ์šฐ ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.

  • 0}๊ณผ ์ผ์น˜ํ•˜๋Š” ๋ฌธ์„œ๊ฐ€ ์—†๋Š” query ๊ฒฝ์šฐ ์ƒˆ ๋ฌธ์„œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ upsert ๋™์ž‘์„ ์ฐธ์กฐํ•˜์„ธ์š”.

  • query์™€ ์ผ์น˜ํ•˜๋Š” ๋‹จ์ผ ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

์—…์„œํŠธ๊ฐ€ ์—ฌ๋Ÿฌ ๋ฒˆ query ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ํ•˜๋ ค๋ฉด ํ•„๋“œ ๊ณ ์œ ํ•˜๊ฒŒ ์ธ๋ฑ์‹ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ ๋Š” ๊ณ ์œ  ์ธ๋ฑ์Šค๋กœ ์—…์„œํŠธ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๊ธฐ๋ณธ๊ฐ’์€ false์ด๋ฉฐ, ์ผ์น˜ํ•˜๋Š” ๋ฌธ์„œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์„ ๋•Œ ์ƒˆ ๋ฌธ์„œ๋ฅผ ์‚ฝ์ž…ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

bypassDocumentValidation

๋ถ€์šธ

์„ ํƒ ์‚ฌํ•ญ. db.collection.findAndModify() ๊ฐ€ ์ž‘์—… ์ค‘์— ๋ฌธ์„œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์šฐํšŒํ•˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์š”๊ตฌ ์‚ฌํ•ญ์„ ์ถฉ์กฑํ•˜์ง€ ์•Š๋Š” ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฒ„์ „ 3.2์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

writeConcern

๋ฌธ์„œ

์„ ํƒ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ์“ฐ๊ธฐ ๊ณ ๋ ค๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฌธ์„œ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ์“ฐ๊ธฐ ๊ณ ๋ ค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ ค๋ฉด ์ƒ๋žตํ•˜์„ธ์š”.

ํŠธ๋žœ์žญ์…˜์—์„œ ์‹คํ–‰๋˜๋Š” ๊ฒฝ์šฐ ์ž‘์—…์— ๋Œ€ํ•œ ์“ฐ๊ธฐ ๊ณ ๋ ค๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •ํ•˜์ง€ ๋งˆ์„ธ์š”. ํŠธ๋žœ์žญ์…˜์— ์“ฐ๊ธฐ ๊ณ ๋ ค๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํŠธ๋žœ์žญ์…˜ ๋ฐ ์“ฐ๊ธฐ ๊ณ ๋ ค๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๋ฒ„์ „ 3.2์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

maxTimeMS

non-negative integer

์„ ํƒ ์‚ฌํ•ญ.

์‹œ๊ฐ„ ์ œํ•œ์„ ๋ฐ€๋ฆฌ์ดˆ ๋‹จ์œ„๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. maxTimeMS์— ๊ฐ’์„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์ž‘์—…์ด ์‹œ๊ฐ„ ์ดˆ๊ณผ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. 0 ๊ฐ’์€ ๋ฐ”์ธ๋”ฉ๋˜์ง€ ์•Š๋Š” ๊ธฐ๋ณธ ๋™์ž‘์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

MongoDB๋Š” db.killOp()์™€ ๋™์ผํ•œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ํ• ๋‹น๋œ ์‹œ๊ฐ„ ์ œํ•œ์„ ์ดˆ๊ณผํ•˜๋Š” ์ž‘์—…์„ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. MongoDB๋Š” ์ง€์ •๋œ ์ค‘๋‹จ ์ง€์  ์ค‘ ํ•˜๋‚˜์—์„œ๋งŒ ์ž‘์—…์„ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

collation

๋ฌธ์„œ

์„ ํƒ ์‚ฌํ•ญ.

์ž‘์—…์— ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ ์ •๋ ฌ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ์ •๋ ฌ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋Œ€์†Œ๋ฌธ์ž ๋ฐ ์•…์„ผํŠธ ํ‘œ์‹œ ๊ทœ์น™๊ณผ ๊ฐ™์€ ๋ฌธ์ž์—ด ๋น„๊ต์— ๋Œ€ํ•œ ์–ธ์–ด๋ณ„ ๊ทœ์น™์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ์ •๋ ฌ ์˜ต์…˜์˜ ๊ตฌ๋ฌธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

collation: {
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}

๋ฐ์ดํ„ฐ ์ •๋ ฌ์„ ์ง€์ •ํ•  ๋•Œ locale ํ•„๋“œ๋Š” ํ•„์ˆ˜์ด๊ณ , ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ์ •๋ ฌ ํ•„๋“œ๋Š” ๋ชจ๋‘ ์„ ํƒ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ํ•„๋“œ์— ๋Œ€ํ•œ ์„ค๋ช…์€ ๋ฐ์ดํ„ฐ ์ •๋ ฌ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๋ฐ์ดํ„ฐ ์ •๋ ฌ์ด ์ง€์ •๋˜์ง€ ์•Š์•˜์ง€๋งŒ ์ปฌ๋ ‰์…˜์— ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ์ •๋ ฌ์ด ์žˆ๋Š” ๊ฒฝ์šฐ( db.createCollection() ์ฐธ์กฐ), ์ž‘์—…์€ ์ปฌ๋ ‰์…˜์— ์ง€์ •๋œ ๋ฐ์ดํ„ฐ ์ •๋ ฌ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ปฌ๋ ‰์…˜ ๋˜๋Š” ์—ฐ์‚ฐ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ ์ •๋ ฌ์ด ์ง€์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ, MongoDB๋Š” ์ด์ „ ๋ฒ„์ „์—์„œ ๋ฌธ์ž์—ด ๋น„๊ต์— ์‚ฌ์šฉ๋œ ๊ฐ„๋‹จํ•œ ์ด์ง„ ๋น„๊ต๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ•œ ์—ฐ์‚ฐ์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ ์ •๋ ฌ์„ ์ง€์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ•„๋“œ๋ณ„๋กœ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ์ •๋ ฌ์„ ์ง€์ •ํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ์ •๋ ฌ๊ณผ ํ•จ๊ป˜ ์ฐพ๊ธฐ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ ์ฐพ๊ธฐ ์™€ ์ •๋ ฌ์—์„œ ๊ฐ๊ฐ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ์ •๋ ฌ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ฒ„์ „ 3.4์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

arrayFilters

๋ฐฐ์—ด

์„ ํƒ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ํ•„ํ„ฐ ๋ฌธ์„œ์˜ ๋ฐฐ์—ด๋กœ, ๋ฐฐ์—ด ํ•„๋“œ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ ์ž‘์—…์„ ์œ„ํ•ด ์ˆ˜์ •ํ•  ๋ฐฐ์—ด ์š”์†Œ๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ ๋ฌธ์„œ์—์„œ $[<identifier>] ํ•„ํ„ฐ๋ง๋œ ์œ„์น˜ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹๋ณ„์ž๋ฅผ ์ •์˜ํ•œ ๋‹ค์Œ ๋ฐฐ์—ด ํ•„ํ„ฐ ๋ฌธ์„œ์—์„œ ์ด๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. ์‹๋ณ„์ž๊ฐ€ ์—…๋ฐ์ดํŠธ ๋ฌธ์„œ์— ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฉด ์‹๋ณ„์ž์— ๋Œ€ํ•œ ๋ฐฐ์—ด ํ•„ํ„ฐ ๋ฌธ์„œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

<identifier>๋Š” ์†Œ๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•˜๋ฉฐ ์˜์ˆซ์ž๋งŒ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ ๋ฌธ์„œ์— ๋™์ผํ•œ ์‹๋ณ„์ž๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํฌํ•จํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์—…๋ฐ์ดํŠธ ๋ฌธ์„œ์˜ ๊ฐ ๊ณ ์œ  ์‹๋ณ„์ž($[identifier])์— ๋Œ€ํ•ด ํ•ด๋‹นํ•˜๋Š” ๋ฐฐ์—ด ํ•„ํ„ฐ ๋ฌธ์„œ๋ฅผ ์ •ํ™•ํžˆ ํ•˜๋‚˜์”ฉ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๋™์ผํ•œ ์‹๋ณ„์ž์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ฐฐ์—ด ํ•„ํ„ฐ ๋ฌธ์„œ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์—…๋ฐ์ดํŠธ ๋ฌธ์— ์‹๋ณ„์ž x๊ฐ€ ํฌํ•จ๋œ ๊ฒฝ์šฐ(์—ฌ๋Ÿฌ ๋ฒˆ), x์— ๋Œ€ํ•œ ๋ณ„๋„์˜ ํ•„ํ„ฐ ๋ฌธ์„œ 2๊ฐœ๊ฐ€ ํฌํ•จ๋œ arrayFilters์— ๋Œ€ํ•ด ๋‹ค์Œ์„ ์ง€์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

// INVALID
[
{ "x.a": { $gt: 85 } },
{ "x.b": { $gt: 80 } }
]

๊ทธ๋Ÿฌ๋‚˜ ๋‹ค์Œ ์˜ˆ์‹œ์™€ ๊ฐ™์ด ๋‹จ์ผ ํ•„ํ„ฐ ๋ฌธ์„œ์—์„œ ๋™์ผํ•œ ์‹๋ณ„์ž์— ๋ณตํ•ฉ ์กฐ๊ฑด์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// Example 1
[
{ $or: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
// Example 2
[
{ $and: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
// Example 3
[
{ "x.a": { $gt: 85 }, "x.b": { $gt: 80 } }
]

์˜ˆ์ œ๋Š” arrayFilters ๋ฐฐ์—ด ์—…๋ฐ์ดํŠธ ์ž‘์—…์— ์ง€์ •์„ ์ฐธ์กฐํ•˜์„ธ์š”.

์ฐธ๊ณ 

์ง‘๊ณ„ ํŒŒ์ดํ”„๋ผ์ธ ์„ ์‚ฌ์šฉํ•˜๋Š” ์—…๋ฐ์ดํŠธ์—๋Š” arrayFilters ์„(๋ฅผ) ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋ฒ„์ „ 3.6์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์„œ

์„ ํƒ ์‚ฌํ•ญ.

๋ณ€์ˆ˜ ๋ชฉ๋ก์ด ์žˆ๋Š” ๋ฌธ์„œ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ฟผ๋ฆฌ ํ…์ŠคํŠธ์—์„œ ๋ณ€์ˆ˜๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ๋ช…๋ น ๊ฐ€๋…์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์„œ ๊ตฌ๋ฌธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

{
<variable_name_1>: <expression_1>,
...,
<variable_name_n>: <expression_n>
}

๋ณ€์ˆ˜๋Š” ํ‘œํ˜„์‹์—์„œ ๋ฐ˜ํ™˜๋œ ๊ฐ’์œผ๋กœ ์„ค์ •๋˜๋ฉฐ ์ดํ›„์—๋Š” ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋ช…๋ น์—์„œ ๋ณ€์ˆ˜ ๊ฐ’์— ์•ก์„ธ์Šคํ•˜๋ ค๋ฉด $<variable_name> ํ˜•์‹์˜ ์ด์ค‘ ๋‹ฌ๋Ÿฌ ๊ธฐํ˜ธ ์ ‘๋‘์‚ฌ ($) ๋ฅผ ๋ณ€์ˆ˜ ์ด๋ฆ„๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.์˜ˆ์‹œ: $targetTotal.

๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ํ•„ํ„ฐ๋งํ•˜๋ ค๋ฉด $expr ์—ฐ์‚ฐ์ž ๋‚ด์—์„œ ๋ณ€์ˆ˜์— ์•ก์„ธ์Šคํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ „์ฒด ์˜ˆ์‹œ let ๋Š” ์—์„œ ๋ณ€์ˆ˜ ์‚ฌ์šฉ์„ ์ฐธ์กฐํ•˜์„ธ์š”.let

๋ฒ„์ „ 5.0์— ์ถ”๊ฐ€.

์ œ๊ฑฐ ์—ฐ์‚ฐ์—์„œ ์ฟผ๋ฆฌ๊ฐ€ ๋ฌธ์„œ์™€ ์ผ์น˜ํ•˜๋ฉด findAndModify()์ด(๊ฐ€) ์ œ๊ฑฐ๋œ ๋ฌธ์„œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ฟผ๋ฆฌ๊ฐ€ ์ œ๊ฑฐํ•  ๋ฌธ์„œ์™€ ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด findAndModify()์ด(๊ฐ€) null(์„)๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ ์—ฐ์‚ฐ์—์„œ findAndModify()๋Š” ๋‹ค์Œ ์ค‘ ํ•œ ๊ฐ€์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • new ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ false์ธ ๊ฒฝ์šฐ:

    • ์ฟผ๋ฆฌ๊ฐ€ ๋ฌธ์„œ์™€ ์ผ์น˜ํ•˜๋ฉด ์ˆ˜์ • ์ „ ๋ฌธ์„œ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

    • ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด null์ด(๊ฐ€) ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

  • new๊ฐ€ true์ธ ๊ฒฝ์šฐ:

    • ์ฟผ๋ฆฌ๊ฐ€ ์ผ์น˜ํ•˜๋Š” ํ•ญ๋ชฉ์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์—…๋ฐ์ดํŠธ๋œ ๋ฌธ์„œ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

    • upsert: true(์ด)๋ฉด์„œ ์ฟผ๋ฆฌ์™€ ์ผ์น˜ํ•˜๋Š” ๋ฌธ์„œ๊ฐ€ ์—†์œผ๋ฉด ์‚ฝ์ž…๋œ ๋ฌธ์„œ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

    • ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด null์ด(๊ฐ€) ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

์ค‘์š”

์–ธ์–ด ์ผ๊ด€์„ฑ

find() ๋ฐ findAndModify() ํ”„๋กœ์ ์…˜์„ ์ง‘๊ณ„์˜ $project ๋‹จ๊ณ„์™€ ์ผ์น˜์‹œํ‚ค๋Š” ์ž‘์—…์˜ ์ผํ™˜์œผ๋กœ,

fields ์˜ต์…˜์—์„œ๋Š” ๋‹ค์Œ ํ˜•์‹์˜ ๋ฌธ์„œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

{ field1: <value>, field2: <value> ... }
ํ”„๋กœ์ ์…˜
์„ค๋ช…

<field>: <1 or true>

ํ•„๋“œ ํฌํ•จ ์—ฌ๋ถ€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์ ์…˜ ๊ฐ’์— 0์ด ์•„๋‹Œ ์ •์ˆ˜๋ฅผ ์ง€์ •ํ•˜๋ฉด ์—ฐ์‚ฐ์€ ํ•ด๋‹น ๊ฐ’์„ true๋กœ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.

<field>: <0 or false>

ํ•„๋“œ ์ œ์™ธ ์—ฌ๋ถ€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

"<field>.$": <1 or true>

$ ๋ฐฐ์—ด ํ”„๋กœ์ ์…˜ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฐ์—ด ํ•„๋“œ์˜ ์ฟผ๋ฆฌ ์กฐ๊ฑด๊ณผ ์ผ์น˜ํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์ ์…˜ ๊ฐ’์— ๋Œ€ํ•ด 0์ด ์•„๋‹Œ ์ •์ˆ˜๋ฅผ ์ง€์ •ํ•˜๋ฉด ์—ฐ์‚ฐ์€ ๊ฐ’์„ true๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

๋ทฐ์—๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

<field>: <array projection>

๋ฐฐ์—ด ํ”„๋กœ์ ์…˜ ์—ฐ์‚ฐ์ž($elemMatch, $slice)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํฌํ•จํ•  ๋ฐฐ์—ด ์š”์†Œ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

๋ทฐ์—๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

<field>: <aggregation expression>

ํ”„๋กœ์ ์…˜๋œ ํ•„๋“œ์˜ ๊ฐ’์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

๋ฆฌํ„ฐ๋Ÿด ๋ฐ ์ง‘๊ณ„ ๋ณ€์ˆ˜ ์‚ฌ์šฉ์„ ํฌํ•จํ•œ ์ง‘๊ณ„ ์‹ ๋ฐ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ƒˆ ํ•„๋“œ๋ฅผ ํ”„๋กœ์ ์…˜ํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด ํ•„๋“œ๋ฅผ ์ƒˆ ๊ฐ’์œผ๋กœ ํ”„๋กœ์ ์…˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํ”„๋กœ์ ์…˜ ๊ฐ’์— ์ˆซ์ž๊ฐ€ ์•„๋‹ˆ๋ฉด์„œ ๋ถ€์šธ์ด ์•„๋‹Œ ๋ฆฌํ„ฐ๋Ÿด(์˜ˆ์‹œ: ๋ฆฌํ„ฐ๋Ÿด ๋ฌธ์ž์—ด, ๋ฐฐ์—ด ๋˜๋Š” ์—ฐ์‚ฐ์ž ํ‘œํ˜„์‹)์„ ์ง€์ •ํ•˜๋ฉด ํ•„๋“œ๊ฐ€ ์ƒˆ ๊ฐ’์œผ๋กœ ํ”„๋กœ์ ์…˜๋ฉ๋‹ˆ๋‹ค.

    • { field: [ 1, 2, 3, "$someExistingField" ] }

    • { field: "New String Value" }

    • { field: { status: "Active", total: { $sum: "$existingArray" } } }

  • ํ•„๋“œ์˜ ๋ฆฌํ„ฐ๋Ÿด ๊ฐ’์„ ํ”„๋กœ์ ์…˜ํ•˜๋ ค๋ฉด ๋‹ค์Œ ์˜ˆ์‹œ์™€ ๊ฐ™์€ $literal ์ง‘๊ณ„ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

    • { field: { $literal: 5 } }

    • { field: { $literal: true } }

    • { field: { $literal: { fieldWithValue0: 0, fieldWithValue1: 1 } } }

๋‚ด์žฅ๋œ ๋ฌธ์„œ์˜ ํ•„๋“œ์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ค์Œ ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„๋“œ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์  ํ‘œ๊ธฐ๋ฒ•(์˜ˆ์‹œ: "field.nestedfield": <value>

  • ์ค‘์ฒฉ๋œ ์–‘์‹(์˜ˆ: { field: { nestedfield: <value> } })

ํ•„๋“œ๋ฅผ ํ‘œ์‹œํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ํ”„๋กœ์ ์…˜์—์„œ _id: 0์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์ง€ ์•Š๋Š” ํ•œ _id ํ•„๋“œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐ˜ํ™˜๋œ ๋ฌธ์„œ์— ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

projection ํ•„๋“œ๋Š” ํฌํ•จ๊ณผ ์ œ์™ธ ์‚ฌ์–‘์„ ๋ชจ๋‘ ํฌํ•จํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‹จ, _id ํ•„๋“œ๋Š” ์˜ˆ์™ธ์ž…๋‹ˆ๋‹ค.

  • ํ•„๋“œ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํฌํ•จํ•˜๋Š” ํ”„๋กœ์ ์…˜์—์„œ _id ํ•„๋“œ๋Š” ๋ช…์‹œ์ ์œผ๋กœ ์ œ์™ธํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ํ•„๋“œ์ž…๋‹ˆ๋‹ค.

  • ํ•„๋“œ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ œ์™ธํ•˜๋Š” ํ”„๋กœ์ ์…˜์—์„œ๋Š” _id ํ•„๋“œ๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ํ•„๋“œ์ด์ง€๋งŒ, _id ํ•„๋“œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ์ ์…˜์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ ์„น์…˜๋„ ๊ฐ™์ด ์ฐธ์กฐํ•˜์„ธ์š”.

์ค‘๋ณต์„ ๋ฐฉ์ง€ํ•˜๋Š” ๊ณ ์œ  ์ธ๋ฑ์Šค ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ์—…์„œํŠธ๋Š” ์ค‘๋ณต ๋ฌธ์„œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฆ„์ด Andy์ธ ๋ฌธ์„œ๊ฐ€ ์—†๊ณ  ์—ฌ๋Ÿฌ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋Œ€๋žต ๋™์‹œ์— ๋‹ค์Œ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋Š” ์˜ˆ์‹œ๋ฅผ ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

db.people.findAndModify(
{
query: { name: "Andy" },
update: { $inc: { score: 1 } },
upsert: true
}
)

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์‚ฝ์ž…ํ•˜๊ธฐ ์ „์— ๋ชจ๋“  findOneAndUpdate() ์ž‘์—…์ด ์ฟผ๋ฆฌ ๋‹จ๊ณ„๋ฅผ ์™„๋ฃŒ ํ•˜๊ณ  name ํ•„๋“œ์— ๊ณ ์œ  ์ธ๋ฑ์Šค๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ, findOneAndUpdate() ์ž‘์—…๋งˆ๋‹ค ์‚ฝ์ž…์ด ๋ฐœ์ƒํ•˜์—ฌ name: Andy ์ด ํฌํ•จ๋œ ์—ฌ๋Ÿฌ ๋ฌธ์„œ๊ฐ€ ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

name ํ•„๋“œ์— ๋Œ€ํ•œ ๊ณ ์œ  ์ธ๋ฑ์Šค๋Š” ํ•˜๋‚˜์˜ ๋ฌธ์„œ๋งŒ ์ƒ์„ฑ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๊ณ ์œ  ์ธ๋ฑ์Šค๊ฐ€ ์ ์šฉ๋˜๋ฉด ์ด์ œ ์—ฌ๋Ÿฌ findOneAndUpdate() ์ž‘์—…์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋™์ž‘์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  • findOneAndUpdate()๋ฒˆ์˜ ์—ฐ์‚ฐ์„ ์ •ํ™•ํžˆ ํ•œ ๋ฒˆ ์‹คํ–‰ํ•˜๋ฉด ์ƒˆ ๋ฌธ์„œ๋ฅผ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋‹ค๋ฅธ findOneAndUpdate() ์ž‘์—…์€ ์ƒˆ๋กœ ์‚ฝ์ž…๋œ ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ฑฐ๋‚˜ ๊ณ ์œ  ํ‚ค ์ถฉ๋Œ๋กœ ์ธํ•ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

    ๋‹ค๋ฅธ findOneAndUpdate() ์ž‘์—…์—์„œ ์ƒˆ๋กœ ์‚ฝ์ž…๋œ ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋ ค๋ฉด ๋‹ค์Œ ์กฐ๊ฑด์ด ๋ชจ๋‘ ์ถฉ์กฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    • target collection์— ์ค‘๋ณต ํ‚ค ์˜ค๋ฅ˜๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๊ณ ์œ  ์ธ๋ฑ์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ์—…๋ฐ์ดํŠธ ์ž‘์—…์ด updateMany ์ด ์•„๋‹ˆ๊ฑฐ๋‚˜ multi ์ด false ์ž…๋‹ˆ๋‹ค.

    • ์—…๋ฐ์ดํŠธ ์ผ์น˜ ์กฐ๊ฑด์€ ๋‘˜ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค:

      • ๋‹จ์ผ ๋™๋“ฑ์„ฑ ์กฐ๊ฑด์ž. ์˜ˆ์‹œ: { "fieldA" : "valueA" }.

      • ๋™๋“ฑ์„ฑ ์กฐ๊ฑด์ž์˜ ๋…ผ๋ฆฌ์  AND. ์˜ˆ์‹œ: { "fieldA" : "valueA", "fieldB" : "valueB" }.

    • ๋™๋“ฑ์„ฑ ์กฐ๊ฑด์ž์˜ ํ•„๋“œ๋Š” ๊ณ ์œ  ์ธ๋ฑ์Šค ํ‚ค ํŒจํ„ด์˜ ํ•„๋“œ์™€ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.

    • ์—…๋ฐ์ดํŠธ ์ž‘์—…์€ ๊ณ ์œ  ์ธ๋ฑ์Šค ํ‚ค ํŒจํ„ด์˜ ํ•„๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ํ‘œ๋Š” ํ‚ค ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋ฉด ์—…๋ฐ์ดํŠธ๋ฅผ ์ดˆ๋ž˜ํ•˜๊ฑฐ๋‚˜ ์‹คํŒจํ•˜๋Š” upsert ์ž‘์—…์˜ ์˜ˆ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

๊ณ ์œ  ์ธ๋ฑ์Šค ํ‚ค ํŒจํ„ด
์—…๋ฐ์ดํŠธ ์ž‘์—…
๊ฒฐ๊ณผ
{ name : 1 }
db.people.updateOne(
{ name: "Andy" },
{ $inc: { score: 1 } },
{ upsert: true }
)

์ผ์น˜ํ•˜๋Š” ๋ฌธ์„œ์˜ score ํ•„๋“œ๊ฐ€ 1์”ฉ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

{ name : 1 }
db.people.updateOne(
{ name: { $ne: "Joe" } },
{ $set: { name: "Andy" } },
{ upsert: true }
)

๊ณ ์œ  ์ธ๋ฑ์Šค ํ‚ค ํŒจํ„ด(name)์˜ ํ•„๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž‘์—…์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

{ name : 1 }
db.people.updateOne(
{ name: "Andy", email: "andy@xyz.com" },
{ $set: { active: false } },
{ upsert: true }
)

๋™๋“ฑ์„ฑ ์กฐ๊ฑด์ž ํ•„๋“œ(name, email)๊ฐ€ ์ธ๋ฑ์Šค ํ‚ค ํ•„๋“œ(name)์™€ ์ผ์น˜ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ž‘์—…์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

์ƒค๋“œ ์ปฌ๋ ‰์…˜์—์„œ findAndModify์„(๋ฅผ) ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋ฐฉ๋ฒ•๋Œ€๋กœ ํ•˜์„ธ์š”.

  • ์ƒค๋“œ 1๊ฐœ๋งŒ์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ๊ฒฝ์šฐ query ํ•„๋“œ์— ๋ถ€๋ถ„ ์ƒค๋“œ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜,

  • query ํ•„๋“œ์˜ ์ „์ฒด ์ƒค๋“œ ํ‚ค์— ๋Œ€ํ•œ ๋™๋“ฑ์„ฑ ์กฐ๊ฑด์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒค๋”ฉ๋œ ์ปฌ๋ ‰์…˜์˜ ๋ฌธ์„œ์—๋Š” ์ƒค๋“œ ํ‚ค ํ•„๋“œ๊ฐ€ ๋ˆ„๋ฝ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒค๋“œ ํ‚ค๊ฐ€ ์—†๋Š” ๋ฌธ์„œ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์ง€์ •ํ•˜๋ ค๋ฉด null ๋™๋“ฑ์„ฑ ๋งค์น˜๋ฅผ ๋‹ค๋ฅธ ํ•„ํ„ฐ ์กฐ๊ฑด(์˜ˆ์‹œ: _id ํ•„๋“œ)๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

{ _id: <value>, <shardkeyfield>: null } // _id of the document missing shard key

์ƒค๋“œ ํ‚ค ํ•„๋“œ๊ฐ€ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” _id ํ•„๋“œ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ๋ฌธ์„œ์˜ ์ƒค๋“œ ํ‚ค ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฝ๊ณ 

์ƒค๋”ฉ๋œ ์ปฌ๋ ‰์…˜์˜ ๋ฌธ์„œ์—๋Š” ์ƒค๋“œ ํ‚ค ํ•„๋“œ๊ฐ€ ๋ˆ„๋ฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์„œ์˜ ์ƒค๋“œ ํ‚ค ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ๋•Œ ์‹ค์ˆ˜๋กœ ์ƒค๋“œ ํ‚ค๋ฅผ ์ œ๊ฑฐํ•˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ์กด ์ƒค๋“œ ํ‚ค ๊ฐ’์„ db.collection.findAndModify()๋กœ ์—…๋ฐ์ดํŠธํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฐ˜๋“œ์‹œ mongos์—์„œ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ƒค๋“œ์—์„œ ์ง์ ‘ ์ž‘์—…์„ ์‹คํ–‰ํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฐ˜๋“œ์‹œ ํŠธ๋žœ์žญ์…˜์—์„œ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜ ์žฌ์‹œ๋„ ๊ฐ€๋Šฅ ์“ฐ๊ธฐ๋กœ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค .

  • ์ „์ฒด ์ƒค๋“œ ํ‚ค์— ๋™๋“ฑ์„ฑ ํ•„ํ„ฐ๋ฅผ ํฌํ•จ์‹œ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ƒค๋”ฉ๋œ ์ปฌ๋ ‰์…˜์˜ ๋ฌธ์„œ์—๋Š” ์ƒค๋“œ ํ‚ค ํ•„๋“œ๊ฐ€ ๋ˆ„๋ฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. db.collection.findAndModify()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์„œ์˜ ๋ˆ„๋ฝ๋œ ์ƒค๋“œ ํ‚ค๋ฅผ ์„ค์ •ํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฐ˜๋“œ์‹œ mongos์—์„œ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ƒค๋“œ์—์„œ ์ง์ ‘ ์ž‘์—…์„ ์‹คํ–‰ํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ์ƒˆ ์ƒค๋“œ ํ‚ค ๊ฐ’์ด null์ด(๊ฐ€) ์•„๋‹Œ ๊ฒฝ์šฐ ํŠธ๋žœ์žญ์…˜ ๋˜๋Š” ์žฌ์‹œ๋„ ๊ฐ€๋Šฅ ์“ฐ๊ธฐ ์ค‘ ํ•˜๋‚˜๋กœ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ์ „์ฒด ์ƒค๋“œ ํ‚ค์— ๋™๋“ฑ์„ฑ ํ•„ํ„ฐ๋ฅผ ํฌํ•จ์‹œ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํŒ

๋ˆ„๋ฝ๋œ ํ‚ค ๊ฐ’์€ null ๋™๋“ฑ์„ฑ ๋งค์น˜์˜ ์ผ๋ถ€๋กœ ๋ฐ˜ํ™˜๋˜๋ฏ€๋กœ null ๊ฐ’ ํ‚ค๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š๋„๋ก ํ•˜๋ ค๋ฉด ์ถ”๊ฐ€ ์ฟผ๋ฆฌ ์กฐ๊ฑด(์˜ˆ: _id ํ•„๋“œ)์„ ์ ์ ˆํžˆ ํฌํ•จํ•˜์„ธ์š”.

๋‹ค์Œ๋„ ์ฐธ์กฐํ•˜์„ธ์š”.

db.collection.findAndModify() ๋ฉ”์„œ๋“œ๋Š” ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๊ทœ์น™์ด ์žˆ๋Š” ์ปฌ๋ ‰์…˜์— ๋ฌธ์„œ๋ฅผ ์‚ฝ์ž…ํ•˜๊ฑฐ๋‚˜ ์—…๋ฐ์ดํŠธํ•  ๋•Œ ๋ฌธ์„œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์žˆ๋Š” bypassDocumentValidation ์˜ต์…˜์— ๋Œ€ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ๋•Œ db.collection.findAndModify() ๋ฉ”์„œ๋“œ์™€ updateOne() ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„œ๋กœ ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

  • ์—ฌ๋Ÿฌ ๋ฌธ์„œ๊ฐ€ ์—…๋ฐ์ดํŠธ ๊ธฐ์ค€๊ณผ ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ db.collection.findAndModify()์— sort๋ฅผ ์ง€์ •ํ•˜์—ฌ ์—…๋ฐ์ดํŠธํ•  ๋ฌธ์„œ์— ์ œ์–ด ์ˆ˜๋‹จ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    updateOne()์€(๋Š”) ์ผ์น˜ํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

  • db.collection.findAndModify()๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด ๋ฌธ์„œ์˜ ์ˆ˜์ • ์ „ ๋ฒ„์ „์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ๋œ ๋ฌธ์„œ๋ฅผ ๋ฐ›์œผ๋ ค๋ฉด new ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

    updateOne() ๋ฉ”์„œ๋“œ๋Š” ์—ฐ์‚ฐ์˜ ์ƒํƒœ๊ฐ€ ํฌํ•จ๋œ WriteResult() ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

    ์—…๋ฐ์ดํŠธ๋œ ๋ฌธ์„œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ ค๋ฉด find() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. ๊ทธ๋Ÿฌ๋‚˜ ์—…๋ฐ์ดํŠธ์™€ ๋ฌธ์„œ ๊ฒ€์ƒ‰ ์‚ฌ์ด์— ๋‹ค๋ฅธ ์—…๋ฐ์ดํŠธ๋กœ ์ธํ•ด ๋ฌธ์„œ๊ฐ€ ์ˆ˜์ •๋˜์—ˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ํ•ด๋‹น ์—…๋ฐ์ดํŠธ๋กœ ์ธํ•ด ๋ฌธ์„œ๊ฐ€ 1๊ฐœ๋งŒ ์ˆ˜์ •๋˜์—ˆ์œผ๋‚˜ ์—ฌ๋Ÿฌ ๋ฌธ์„œ๊ฐ€ ์ผ์น˜ํ•œ ๊ฒฝ์šฐ, ์—…๋ฐ์ดํŠธ๋œ ๋ฌธ์„œ๋ฅผ ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ถ”๊ฐ€ ๋กœ์ง์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‹จ์ผ ๋ฌธ์„œ๋ฅผ ์ˆ˜์ •ํ•  ๋•Œ๋Š” db.collection.findAndModify() ๋ฉ”์„œ๋“œ ๋ฐ updateOne() ๋ฉ”์„œ๋“œ ๋‘˜ ๋‹ค ๋ฌธ์„œ๋ฅผ ์›์ž ๋‹จ์œ„๋กœ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋“ค์˜ ์ƒํ˜ธ์ž‘์šฉ๊ณผ ์—ฐ์‚ฐ ์ˆœ์„œ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์›์ž์„ฑ ๋ฐ ํŠธ๋žœ์žญ์…˜์„ ์ฐธ์กฐํ•˜์„ธ์š”.

db.collection.findAndModify()๋Š” ๋ถ„์‚ฐ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ค‘์š”

๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๋ถ„์‚ฐ ํŠธ๋žœ์žญ์…˜์€ ๋‹จ์ผ ๋ฌธ์„œ ์“ฐ๊ธฐ์— ๋น„ํ•ด ๋” ํฐ ์„ฑ๋Šฅ ๋น„์šฉ์ด ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ๋ถ„์‚ฐ ํŠธ๋žœ์žญ์…˜์˜ ๊ฐ€์šฉ์„ฑ์ด ํšจ๊ณผ์ ์ธ ์Šคํ‚ค๋งˆ ์„ค๊ณ„๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ๋น„์ •๊ทœํ™”๋œ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ (๋‚ด์žฅ๋œ ๋ฌธ์„œ ๋ฐ ๋ฐฐ์—ด) ์€ ๊ณ„์†ํ•ด์„œ ๋ฐ์ดํ„ฐ ๋ฐ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์ตœ์ ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ๋Œ€๋ถ€๋ถ„์˜ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ๋ชจ๋ธ๋งํ•˜๋ฉด ๋ถ„์‚ฐ ํŠธ๋žœ์žญ์…˜์˜ ํ•„์š”์„ฑ์ด ์ตœ์†Œํ™”๋ฉ๋‹ˆ๋‹ค.

์ถ”๊ฐ€ ํŠธ๋žœ์žญ์…˜ ์‚ฌ์šฉ ๊ณ ๋ ค ์‚ฌํ•ญ(์˜ˆ: ๋Ÿฐํƒ€์ž„ ์ œํ•œ ๋ฐ oplog ํฌ๊ธฐ ์ œํ•œ)์€ ํ”„๋กœ๋•์…˜ ๊ณ ๋ ค์‚ฌํ•ญ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

ํŠธ๋žœ์žญ์…˜์ด ๊ต์ฐจ ์ƒค๋“œ ์“ฐ๊ธฐ ํŠธ๋žœ์žญ์…˜(write transaction)์ด ์•„๋‹Œ ๊ฒฝ์šฐ ๋ถ„์‚ฐ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์ปฌ๋ ‰์…˜๊ณผ ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

upsert: true์ธ db.collection.findAndModify()๋Š” ๊ธฐ์กด ์ปฌ๋ ‰์…˜์ด๋‚˜ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ปฌ๋ ‰์…˜์—์„œ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ปฌ๋ ‰์…˜์—์„œ ์‹คํ–‰ํ•˜๋ฉด ์ž‘์—…์ด ์ปฌ๋ ‰์…˜์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๋‹ค์Œ๋„ ์ฐธ์กฐํ•˜์„ธ์š”.

ํŠธ๋žœ์žญ์…˜์—์„œ ์‹คํ–‰๋˜๋Š” ๊ฒฝ์šฐ ์ž‘์—…์— ๋Œ€ํ•œ ์“ฐ๊ธฐ ๊ณ ๋ ค๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •ํ•˜์ง€ ๋งˆ์„ธ์š”. ํŠธ๋žœ์žญ์…˜์— ์“ฐ๊ธฐ ๊ณ ๋ ค๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํŠธ๋žœ์žญ์…˜ ๋ฐ ์“ฐ๊ธฐ ๊ณ ๋ ค๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

db.collection.findAndModify() ์ž‘์—…์ด ๋ฌธ์„œ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์ฐพ์•„์„œ ์ˆ˜์ •ํ•˜๋ฉด ์ž‘์—…์€ oplog(์ž‘์—… ๋กœ๊ทธ)์— ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ž‘์—…์ด ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ๋ฌธ์„œ๋ฅผ ์ฐพ์ง€ ๋ชปํ•˜๋ฉด ์ž‘์—…์€ oplog์— ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

MongoDB ์—์„œ 5.0 findAndModify ๋ช…๋ น์ด ์ƒค๋”ฉ๋œ ํด๋Ÿฌ์Šคํ„ฐ ์—์„œ ์‹คํ–‰mongos ๋˜๋Š” ๊ฒฝ์šฐ,writeConcernError ์ƒค๋“œ ์‘๋‹ต์— ์˜ค๋ฅ˜๊ฐ€ ํฌํ•จ๋œ ๊ฒฝ์šฐ ๊ฐ€ ๋ฌธ์„œ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ๋ฉ”์„œ๋“œ๋Š” ๋ฌธ์„œ๊ฐ€ ์ฟผ๋ฆฌ ๊ธฐ์ค€๊ณผ ์ผ์น˜ํ•˜๋Š” ์‚ฌ๋žŒ ์ปฌ๋ ‰์…˜์˜ ๊ธฐ์กด ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

db.people.findAndModify({
query: { name: "Tom", state: "active", rating: { $gt: 10 } },
sort: { rating: 1 },
update: { $inc: { score: 1 } }
})

์ด ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ ์ž‘์—…์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  1. query์€(๋Š”) name ํ•„๋“œ์˜ ๊ฐ’์ด Tom(์ด)๊ณ , state ํ•„๋“œ์˜ ๊ฐ’์ด active(์ด)๊ณ , rating ํ•„๋“œ์˜ ๊ฐ’์ด 10 greater than์ธ people ์ปฌ๋ ‰์…˜์—์„œ ๋ฌธ์„œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.

  2. sort์€(๋Š”) ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ๋ฌธ์„œ๊ฐ€ query ์กฐ๊ฑด์„ ์ถฉ์กฑํ•  ๊ฒฝ์šฐ, ์ด ๋ฉ”์„œ๋“œ๋Š” ์ด sort(์œผ)๋กœ ์ •๋ ฌ๋œ ์ฒซ ๋ฒˆ์งธ ๋ฌธ์„œ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ๋กœ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  3. increments์€(๋Š”) score ํ•„๋“œ์˜ ๊ฐ’์„ 1์”ฉ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

  4. ์ด ๋ฉ”์„œ๋“œ๋Š” ์ด ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•ด ์„ ํƒ๋œ ์›๋ณธ(์ฆ‰ ์ˆ˜์ • ์ „) ๋ฌธ์„œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

    {
    "_id" : ObjectId("50f1e2c99beb36a0f45c6453"),
    "name" : "Tom",
    "state" : "active",
    "rating" : 100,
    "score" : 5
    }

    ์—…๋ฐ์ดํŠธ๋œ ๋ฌธ์„œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ ค๋ฉด ๋ฉ”์„œ๋“œ์— new:true ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

    query ์กฐ๊ฑด๊ณผ ์ผ์น˜ํ•˜๋Š” ๋ฌธ์„œ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ ์ด ๋ฉ”์„œ๋“œ๋Š” null์„(๋ฅผ) ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ๋ฉ”์„œ๋“œ์—๋Š” ์ผ์น˜ํ•˜๋Š” ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ฑฐ๋‚˜, ์ผ์น˜ํ•˜๋Š” ๋ฌธ์„œ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ์ƒˆ ๋ฌธ์„œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” update ์—ฐ์‚ฐ์˜ upsert: true ์˜ต์…˜์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

db.people.findAndModify({
query: { name: "Gus", state: "active", rating: 100 },
sort: { rating: 1 },
update: { $inc: { score: 1 } },
upsert: true
})

์ด ๋ฉ”์„œ๋“œ๊ฐ€ ์ผ์น˜ํ•˜๋Š” ๋ฌธ์„œ๋ฅผ ์ฐพ์œผ๋ฉด ์—…๋ฐ์ดํŠธ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

์ด ๋ฉ”์„œ๋“œ๊ฐ€ ์ผ์น˜ํ•˜๋Š” ๋ฌธ์„œ๋ฅผ ์ฐพ์ง€ ๋ชปํ•˜๋ฉด ์ƒˆ ๋ฌธ์„œ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ์— sort ์˜ต์…˜์ด ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ๋นˆ ๋ฌธ์„œ { }์ด(๊ฐ€) ์›๋ณธ(์ˆ˜์ • ์ „) ๋ฌธ์„œ๋กœ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

{ }

์ด ๋ฉ”์„œ๋“œ์— sort ์˜ต์…˜์ด ํฌํ•จ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋Š” null์ด(๊ฐ€) ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

null

๋‹ค์Œ ๋ฉ”์„œ๋“œ์—๋Š” upsert: true ์˜ต์…˜๊ณผ new:true ์˜ต์…˜์ด ๋ชจ๋‘ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ์ผ์น˜ํ•˜๋Š” ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์—…๋ฐ์ดํŠธ๋œ ๋ฌธ์„œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜, ์ผ์น˜ํ•˜๋Š” ๋ฌธ์„œ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ๋ฌธ์„œ๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ  ์ƒˆ๋กœ ์‚ฝ์ž…๋œ ๋ฌธ์„œ๋ฅผ value ํ•„๋“œ์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์‹œ์—์„œ๋Š” people ์ปฌ๋ ‰์…˜์˜ ์–ด๋–ค ๋ฌธ์„œ๋„ query ์กฐ๊ฑด๊ณผ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

db.people.findAndModify({
query: { name: "Pascal", state: "active", rating: 25 },
sort: { rating: 1 },
update: { $inc: { score: 1 } },
upsert: true,
new: true
})

์ด ๋ฉ”์„œ๋“œ๋Š” ์ƒˆ๋กœ ์‚ฝ์ž…๋œ ๋ฌธ์„œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

{
"_id" : ObjectId("50f49ad6444c11ac2448a5d6"),
"name" : "Pascal",
"rating" : 25,
"score" : 1,
"state" : "active"
}

๋‹ค์Œ ์˜ˆ์‹œ์—์„œ๋Š” rating ํ•„๋“œ์— sort ์‚ฌ์–‘์„ ํฌํ•จ์‹œํ‚ด์œผ๋กœ์จ, state ๊ฐ’์ด active(์ด)๋ฉด์„œ ์ผ์น˜ํ•˜๋Š” ๋ฌธ์„œ ์ค‘ rating ๊ฐ’์ด ๊ฐ€์žฅ ๋‚ฎ์€ ๋‹จ์ผ ๋ฌธ์„œ๋ฅผ people ์ปฌ๋ ‰์…˜์—์„œ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

db.people.findAndModify(
{
query: { state: "active" },
sort: { rating: 1 },
remove: true
}
)

์ด ๋ฉ”์„œ๋“œ๋Š” ์‚ญ์ œ๋œ ๋ฌธ์„œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

{
"_id" : ObjectId("52fba867ab5fdca1299674ad"),
"name" : "XYZ123",
"score" : 1,
"state" : "active",
"rating" : 3
}

๋ฒ„์ „ 3.4์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ์ •๋ ฌ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋Œ€์†Œ๋ฌธ์ž ๋ฐ ์•…์„ผํŠธ ํ‘œ์‹œ ๊ทœ์น™๊ณผ ๊ฐ™์€ ๋ฌธ์ž์—ด ๋น„๊ต์— ๋Œ€ํ•œ ์–ธ์–ด๋ณ„ ๊ทœ์น™์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ปฌ๋ ‰์…˜ myColl์—๋Š” ๋‹ค์Œ ๋ฌธ์„œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

{ _id: 1, category: "cafรฉ", status: "A" }
{ _id: 2, category: "cafe", status: "a" }
{ _id: 3, category: "cafE", status: "a" }

๋‹ค์Œ ์ž‘์—…์—๋Š” ๋ฐ์ดํ„ฐ ์ •๋ ฌ ์˜ต์…˜์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

db.myColl.findAndModify({
query: { category: "cafe", status: "a" },
sort: { category: 1 },
update: { $set: { status: "Updated" } },
collation: { locale: "fr", strength: 1 }
});

์—ฐ์‚ฐ์€ ๋‹ค์Œ ๋ฌธ์„œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

{ "_id" : 1, "category" : "cafรฉ", "status" : "A" }

์ฐธ๊ณ 

์ง‘๊ณ„ ํŒŒ์ดํ”„๋ผ์ธ ์„ ์‚ฌ์šฉํ•˜๋Š” ์—…๋ฐ์ดํŠธ์—๋Š” arrayFilters ์„(๋ฅผ) ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐฐ์—ด ํ•„๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ๋•Œ ์—…๋ฐ์ดํŠธํ•  ๋ฐฐ์—ด ์š”์†Œ๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” arrayFilters๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ 

์ง‘๊ณ„ ํŒŒ์ดํ”„๋ผ์ธ ์„ ์‚ฌ์šฉํ•˜๋Š” ์—…๋ฐ์ดํŠธ์—๋Š” arrayFilters ์„(๋ฅผ) ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ๋ฌธ์„œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปฌ๋ ‰์…˜ students๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

db.students.insertMany( [
{ "_id" : 1, "grades" : [ 95, 92, 90 ] },
{ "_id" : 2, "grades" : [ 98, 100, 102 ] },
{ "_id" : 3, "grades" : [ 95, 110, 100 ] }
] )

grades ๋ฐฐ์—ด์—์„œ 100๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€ ์š”์†Œ๋ฅผ ๋ชจ๋‘ ์—…๋ฐ์ดํŠธํ•˜๋ ค๋ฉด ํ•„ํ„ฐ๋ง๋œ ์œ„์น˜ ์—ฐ์‚ฐ์ž $[<identifier>]์„(๋ฅผ) db.collection.findAndModify() ๋ฉ”์„œ๋“œ์˜ arrayFilters ์˜ต์…˜๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์„ธ์š”.

db.students.findAndModify({
query: { grades: { $gte: 100 } },
update: { $set: { "grades.$[element]" : 100 } },
arrayFilters: [ { "element": { $gte: 100 } } ]
})

์ด ์—ฐ์‚ฐ์€ ๋‹จ์ผ ๋ฌธ์„œ์˜ grades ํ•„๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. ์—ฐ์‚ฐ์ด ์™„๋ฃŒ๋œ ํ›„ ์ปฌ๋ ‰์…˜์— ํฌํ•จ๋˜๋Š” ๋ฌธ์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

{ "_id" : 1, "grades" : [ 95, 92, 90 ] }
{ "_id" : 2, "grades" : [ 98, 100, 100 ] }
{ "_id" : 3, "grades" : [ 95, 110, 100 ] }

์ฐธ๊ณ 

์ง‘๊ณ„ ํŒŒ์ดํ”„๋ผ์ธ ์„ ์‚ฌ์šฉํ•˜๋Š” ์—…๋ฐ์ดํŠธ์—๋Š” arrayFilters ์„(๋ฅผ) ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ๋ฌธ์„œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปฌ๋ ‰์…˜ students2๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

db.students2.insertMany( [
{
"_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 6 },
{ "grade" : 85, "mean" : 90, "std" : 4 },
{ "grade" : 85, "mean" : 85, "std" : 6 }
]
},
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 75, "std" : 6 },
{ "grade" : 87, "mean" : 90, "std" : 3 },
{ "grade" : 85, "mean" : 85, "std" : 4 }
]
}
] )

๋‹ค์Œ ์ž‘์—…์€ ํ•„๋“œ๊ฐ€ ์ธ ๋ฌธ์„œ๋ฅผ ์ฐพ๊ณ  _id 1 ํ•„ํ„ฐ๋ง๋œ ์œ„์น˜ ์—ฐ์‚ฐ์ž ๋ฅผ ์™€ ํ•จ๊ป˜ $[<identifier>] ์‚ฌ์šฉํ•˜์—ฌ arrayFilters mean grades ๋“ฑ๊ธ‰์ด ๋” ๋†’์€ ๋ฐฐ์—ด์˜ ๋ชจ๋“  ์š”์†Œ์— ๋Œ€ํ•ด ๋ฅผ 85 ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. ์ด์ƒ์ž…๋‹ˆ๋‹ค.

db.students2.findAndModify({
query: { _id : 1 },
update: { $set: { "grades.$[elem].mean" : 100 } },
arrayFilters: [ { "elem.grade": { $gte: 85 } } ]
})

์ด ์—ฐ์‚ฐ์€ ๋‹จ์ผ ๋ฌธ์„œ์˜ grades ํ•„๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. ์—ฐ์‚ฐ์ด ์™„๋ฃŒ๋œ ํ›„ ์ปฌ๋ ‰์…˜์— ํฌํ•จ๋˜๋Š” ๋ฌธ์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

{
"_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 6 },
{ "grade" : 85, "mean" : 100, "std" : 4 },
{ "grade" : 85, "mean" : 100, "std" : 6 }
]
}
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 75, "std" : 6 },
{ "grade" : 87, "mean" : 90, "std" : 3 },
{ "grade" : 85, "mean" : 85, "std" : 4 }
]
}

db.collection.findAndModify()๋Š” ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•œ ์ง‘๊ณ„ ํŒŒ์ดํ”„๋ผ์ธ์„ ์ธ์ˆ˜๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ดํ”„๋ผ์ธ์€ ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๊ตฌ์„ฑ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ง‘๊ณ„ ํŒŒ์ดํ”„๋ผ์ธe์„ ์‚ฌ์šฉํ•˜๋ฉด ํ˜„์žฌ ํ•„๋“œ ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์กฐ๊ฑด๋ถ€ ์—…๋ฐ์ดํŠธ๋ฅผ ํ‘œํ˜„ํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ํ•„๋“œ์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•œ ํ•„๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋“ฑ ๋ณด๋‹ค ํ‘œํ˜„๋ ฅ์ด ํ’๋ถ€ํ•œ ์—…๋ฐ์ดํŠธ ๊ตฌ๋ฌธ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ ์˜ˆ๋กœ ๋‹ค์Œ ๋ฌธ์„œ๋ฅผ ์‚ฌ์šฉํ•ด students2 ์ปฌ๋ ‰์…˜์„ ์ƒ์„ฑํ•˜์„ธ์š”.

db.students2.insertMany( [
{
"_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 6 },
{ "grade" : 85, "mean" : 90, "std" : 4 },
{ "grade" : 85, "mean" : 85, "std" : 6 }
]
},
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 75, "std" : 6 },
{ "grade" : 87, "mean" : 90, "std" : 3 },
{ "grade" : 85, "mean" : 85, "std" : 4 }
]
}
] )

๋‹ค์Œ ์—ฐ์‚ฐ์€ _id ํ•„๋“œ๊ฐ€ 1์ธ ๋ฌธ์„œ๋ฅผ ์ฐพ๊ณ , ์ง‘๊ณ„ ํŒŒ์ดํ”„๋ผ์ธ์„ ์‚ฌ์šฉํ•˜์—ฌ grades ํ•„๋“œ์—์„œ ์ƒˆ ํ•„๋“œ total์„(๋ฅผ) ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

db.students2.findAndModify( {
query: { "_id" : 1 },
update: [ { $set: { "total" : { $sum: "$grades.grade" } } } ], // The $set stage is an alias for ``$addFields`` stage
new: true
} )

์ฐธ๊ณ 

์ด ํŒŒ์ดํ”„๋ผ์ธ์— ์‚ฌ์šฉ๋œ $set์€(๋Š”) ์—…๋ฐ์ดํŠธ ์—ฐ์‚ฐ์ž $set์ด(๊ฐ€) ์•„๋‹Œ ์ง‘๊ณ„ ๋‹จ๊ณ„ $set์„(๋ฅผ) ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

์ด ์—ฐ์‚ฐ์€ ์—…๋ฐ์ดํŠธ๋œ ๋ฌธ์„œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

{
"_id" : 1,
"grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 90, "std" : 4 }, { "grade" : 85, "mean" : 85, "std" : 6 } ],
"total" : 250
}

๋ฒ„์ „ 5.0์— ์ถ”๊ฐ€.

๋ช…๋ น์˜ ๋‹ค๋ฅธ ๊ณณ์—์„œ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜๋ ค๋ฉด let ์˜ต์…˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ 

๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ํ•„ํ„ฐ๋งํ•˜๋ ค๋ฉด $expr ์—ฐ์‚ฐ์ž ๋‚ด์—์„œ ๋ณ€์ˆ˜์— ์•ก์„ธ์Šคํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ปฌ๋ ‰์…˜ cakeFlavors์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค:

db.cakeFlavors.insertMany( [
{ _id: 1, flavor: "chocolate" },
{ _id: 2, flavor: "strawberry" },
{ _id: 3, flavor: "cherry" }
] )

๋‹ค์Œ ์˜ˆ์‹œ์—์„œ๋Š” let์˜ targetFlavor ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜๊ณ , ์ด ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ผ€์ดํฌ ๋ง›์„ ์ฒด๋ฆฌ์—์„œ ์˜ค๋ Œ์ง€๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

db.cakeFlavors.findAndModify( {
query: {
$expr: { $eq: [ "$flavor", "$$targetFlavor" ] }
},
update: { flavor: "orange" },
let: { targetFlavor: "cherry" }
} )