Skip to content

Mongoose document udpate ๋ฐฉ์‹

yejineee edited this page Nov 27, 2020 · 4 revisions

๐ŸŽฏ ํ•ด๊ฒฐํ•˜๊ณ  ์‹ถ์—ˆ๋˜ ๊ฒƒ

Account ์ปฌ๋ ‰์…˜์€ transaction ๋„ํ๋จผํŠธ์˜ objectId๋ฅผ ์ž์‹ ์˜ ํ•„๋“œ์ธ transactions์— ์ถ”๊ฐ€ํ•˜์—ฌ์•ผ ํ•œ๋‹ค.

๊ทธ ๊ณผ์ •์€ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์ผ์„ ํ•ด์•ผ ํ•œ๋‹ค.

  1. Account Object Id๋กœ Account ๋„ํ๋จผํŠธ๋ฅผ ์ฐพ๋Š”๋‹ค.

  2. ๊ทธ ๋„ํ๋จผํŠธ์˜ trasactions์— ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“  transaction ๋„ํ๋จผํŠธ์˜ Object Id๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

๊ณต๋™๊ฐ€๊ณ„๋ถ€๋ฅผ ๊ด€๋ฆฌํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด, ๋™์‹œ์— ์—ฌ๋Ÿฌ ์‚ฌ๋žŒ์ด ๊ฑฐ๋ž˜๋‚ด์—ญ์„ ์ถ”๊ฐ€, ์‚ญ์ œ ๋“ฑ์˜ ์š”์ฒญ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฏ€๋กœ, ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  ๋””๋น„์— ๋Œ€ํ•œ ์ ‘๊ทผ ์š”์ฒญ์ด ์œ ํšจํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค.

๋ชฝ๊ตฌ์Šค์—์„œ Atomic Update ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋ณด์ž.

โœ… Updateํ•˜๋Š” ์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ•๋“ค

์šฐ์„  update๋ฅผ ํ•˜๋Š” ์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ•๋“ค์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋”ฐ.

  1. in-memory update

    const targetAccount = await this.findById(accountObjId).exec();
    targetAccount.transactions.push(transactionObjId);
    await targetAccount.save();

    find๋ฅผ ํ•ด์„œ ๊ฐ€์ ธ์˜จ ๋„ํ๋จผํŠธ๋ฅผ updateํ•œ ํ›„ saveํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ์ด ๋ฐฉ์‹์€ ๋„ํ๋จผํŠธ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„, save๊ฐ€ ๋˜๊ธฐ ์ „์— ๋‹ค๋ฅธ ์ฟผ๋ฆฌ์— ์˜ํ•ด ๋„ํ๋จผํŠธ๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋‹ค. ๋งŽ์€ ๊ฒฝ์šฐ์—[

  2. findOneAndUpdate()

User.findByIdAndUpdate(id, { $push: { createdEvents: eventId } }).exec();

๋ชฝ๊ตฌ์Šค ๊ณต์‹๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด findOndAndUpdate๋Š” atomicํ•˜๋‹ค๊ณ  ํ•œ๋‹ค.

With the exception of an unindexed upsert, findOneAndUpdate() is atomic.

$push operator๋Š” ๋ฐฐ์—ด์— ๊ฐ’์„ ์ถ”๊ฐ€ํ•œ๋‹ค. ์ด ๋ฐฉ์‹์œผ๋กœ id์— ํ•ด๋‹นํ•˜๋Š” ๋„ํ๋จผํŠธ๋ฅผ ์ฐพ์•„์„œ createdEvents ๋ฐฐ์—ด์— eventId๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

  1. Update

update๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ atomicํ•˜๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ํ•„ํ„ฐ๋ฅผ ๋„ฃ์–ด์ฃผ๊ณ , ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ ์‹คํ–‰ํ•  ๋„ํ๋จผํŠธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ๋ฉด ๋œ๋‹ค. findOneAndUpdate์™€ ๋‹ค๋ฅธ ์ ์€ findOneAndUpdate๋Š” ๋„ํ๋จผํŠธ๋ฅผ ๋ฆฌํ„ดํ•ด์ฃผ์ง€๋งŒ, update๋Š” ๋„ํ๋จผํŠธ๋ฅผ ๋ฆฌํ„ดํ•˜์ง€ ์•Š๋Š”๋‹ค.

PersonModel.update(
    { _id: person._id }, 
    { $push: { friends: friend } },
    done
);

โœ”๏ธ ์šฐ๋ฆฌ๊ฐ€ ์„ ํƒํ•œ ๋ฐฉ๋ฒ•

this.findByIdAndUpdate(accountObjId, {
    $push: { transactions: transactionObjId },
}).exec();

findOneAndUpdate๋Š” atomicํ•˜๋‹ค๊ณ  ํ•œ๋‹ค. ์šฐ๋ฆฌ๋Š” Account ์ปฌ๋ ‰์…˜์—์„œ Object Id๋ฅผ ์ฐพ์•„์„œ update๋ฅผ ํ•ด์ค˜์•ผํ•˜๋ฏ€๋กœ, findByIdAndUpdate ๊ฐ€ ์ ํ•ฉํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜์˜€๋‹ค. findByIdAndUpdate ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ findOneAndUpdate๋ฅผ ๋ถˆ๋Ÿฌ์ค€๋‹ค๊ณ  ํ•˜๋‹ˆ, findByIdAndUpdate ๋˜ํ•œ atomic ํ•  ๊ฒƒ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

๐Ÿ†• ๊ทธ ์™ธ ์ƒˆ๋กญ๊ฒŒ ์•Œ๊ฒŒ๋œ ๊ฒƒ!

  • exec

update๋งŒ ํ•˜๋ฉด ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๋Š” ์ค„ ์•Œ์•˜๋Š”๋ฐ, ๊ณต์‹๋ฌธ์„œ์˜ ์˜ˆ์ œ๋ฅผ ๋ณด๋ฉด, exec() ๋ฅผ ๋งˆ์ง€๋ง‰์— ๋ถˆ๋Ÿฌ์˜ค๋Š”๊ฒŒ ์žˆ์—ˆ๋‹ค. exec๋ฅผ ์™œ ํ•ด์ฃผ๋Š” ๊ฑธ๊นŒ???

๊ทธ๋ƒฅ query๋ฌธ์„ ํ˜ธ์ถœํ•˜๋ฉด, ์‹ค์ œ์ ์œผ๋กœ ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.

์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ์œ ๋ฌด ์— ๋”ฐ๋ผ ์‹คํ–‰์ด ๋‹ฌ๋ผ์ง€๊ฒŒ ๋œ๋‹ค.

์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์žˆ์œผ๋ฉด ์‹คํ–‰์ด ๋˜๊ณ , ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์—†์œผ๋ฉด ์ฟผ๋ฆฌ๋ฅผ ๋ฆฌํ„ดํ•˜๊ฒŒ ๋œ๋‹ค.

A.findByIdAndUpdate(id, update, options, callback) // executes
A.findByIdAndUpdate(id, update, callback) // executes
A.findByIdAndUpdate(id, update, options)  // returns Query
A.findByIdAndUpdate(id, update)           // returns Query
A.findByIdAndUpdate()                     // returns Query

๋”ฐ๋ผ์„œ, ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ์—†์ด ๋ฐ”๋กœ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰์‹œํ‚ค๋ ค๋ฉด, update() ํ˜ธ์ถœ ํ›„ exec()๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

const q = Model.where({ _id: id });
q.update({ $set: { name: 'bob' }}).update(); // not executed
q.update({ $set: { name: 'bob' }}).exec(); // executed
  • upsert option

    upsert๋ฅผ true๋กœ ์ฃผ๋ฉด, document๊ฐ€ ์žˆ์œผ๋ฉด update๋ฅผ ํ•˜๊ณ , ์—†์œผ๋ฉด, filter์™€ update๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ์ƒ์„ฑํ•œ๋‹ค.

    const filter = { name: 'Will Riker' };
    const update = { age: 29 };
    
    await Character.countDocuments(filter); // 0
    
    let doc = await Character.findOneAndUpdate(filter, update, {
      new: true,
      upsert: true // Make this update into an upsert
    });
    doc.name; // Will Riker
    doc.age; // 29

์ถœ์ฒ˜

Push items into mongo array via mongoose

https://ddcode.net/2019/05/12/is-mongodb-findoneandupdate-thread-safe/

https://mongoosejs.com/docs/tutorials/findoneandupdate.html

๐Ÿ“Œ Project

๐Ÿค Rules

๐Ÿ“š Documents

๐Ÿข๊ตฌ์กฐ

๐Ÿง๋…ผ์˜

โšฝ๏ธ TroubleShooting

๐Ÿ’ฌ Memoirs

1 ์ฃผ์ฐจ
2 ์ฃผ์ฐจ
3 ์ฃผ์ฐจ
4 ์ฃผ์ฐจ
5 ์ฃผ์ฐจ

๐Ÿ“ ํ”ผ์–ด์„ธ์…˜

<2์ฃผ์ฐจ> 24๊ทธ๋ฃน 25๊ทธ๋ฃน

<3์ฃผ์ฐจ> 24๊ทธ๋ฃน 25๊ทธ๋ฃน

<4์ฃผ์ฐจ> 24๊ทธ๋ฃน 25๊ทธ๋ฃน 26๊ทธ๋ฃน 27๊ทธ๋ฃน

Clone this wiki locally