Mongoose#Documentのsaveメソッドで更新できないとき

Last updated at

warning

この記事は最終更新から3年以上経っています。情報が古くなっている可能性が高いです。

概要

仕事でMongooseを使ったプロジェクトをやっていたときに、ドキュメントが更新されない事象に遭遇。 そのまんまは書けないが、モデルは大体こんな感じで

const Photo = mongoose.Model('Photo', {
  // オーナユーザID
  owner: ObjectId,
  // 写真のメタ情報
  metadata: Object
})

スキーマがきっちり決まっていない外部のJSON(Object)をそのままDBに突っ込むということをしていた。

ちなみに保存処理はこんな感じ。

const photos = await Photo.find({/* てきとうなクエリ */})

return Promise.all(photos.map(photo => {
  photo.metadata.tags = photo.metadata.tags ? ['myawesomeapp', ...photo.metadata.tags] : ['myawesomeapp']

  return photo.save()
})

しかし実行してデータを確認してみるとmetadata.tagsmyawesomeappがない...。

原因

Mongooseがドキュメントに変更があったと認識していない為、保存処理が走っていない模様。

対処

Document#markModifiedを呼んでからsaveメソッドを呼ぶ。

さっきの例だとこんな感じ。

const photos = await Photo.find({/* てきとうなクエリ */})

return Promise.all(photos.map(photo => {
  photo.metadata.tags = photo.metadata.tags ? ['myawesomeapp', ...photo.metadata.tags] : ['myawesomeapp']

  photo.markModified('metadata') // 追加

  return photo.save()
})

参考

https://stackoverflow.com/a/39823651 https://qiita.com/Eiryyy/items/2b287023256e67172203