[Mongoose] 特定の field が変更されたかは isDirectModified, isModified, modifiedPaths で確認できる

Mongoose では document の特定の field に変更があったかどうかを isDirectModified や isModified, modifiedPaths などの method で確認できます。

mongoose | マングース

Ruby on Rails の ActiveRecord でいうところの changed? や 属性名_changed? と似たような機能が Mongoose でも提供されています。

では、1つずつ紹介していきましょう。

Document#isDirectModified(path)

isDirectModified メソッドは引数に指定した field 自身が変更されていれば true をそうでなければ false を返します。

doc.set('documents.0.title', 'changed');
 
// 'documents.0.title' 自体が変更されているので true を返す
doc.isDirectModified('documents.0.title') // true
 
// 'documents' の下の階層で変更されているが 'documents' 自体は変更されていないので false を返す
doc.isDirectModified('documents') // false

Document#isModified([path])

isModified メソッドは引数に指定した field に関係がある箇所が変更されていれば true をそうでなければ false を返します。

doc.set('documents.0.title', 'changed');
 
// 変更された field とそれを含む上の階層は true を返す
doc.isModified()                    // true
doc.isModified('documents')         // true
doc.isModified('documents.0.title') // true
 
// 変更されてない field を指定すると false を返す
doc.isModified('something')         // false
 
// 'documents' の下の階層で変更されているが 'documents' 自体は変更されていないので false を返す
doc.isDirectModified('documents')   // false

Document#modifiedPaths()

modifiedPaths メソッドは変更があった field 名を Array で返します。

doc.set('name', 'test name');
doc.set('documents.0.title', 'changed');
 
doc.modifiedPaths()
[ 'name',
  'documents.0.title' ]

これらの機能をうまく使ってロジックをすっきり書けるといいですね。