お気づきのように、mongooseのデフォルトでは、このような配列にデータを「埋め込む」と、_id
が取得されます。 独自のサブドキュメントプロパティの一部としての各配列エントリの値。更新するアイテムのインデックスを決定するために、実際にこの値を使用できます。これを行うMongoDBの方法は、位置的な$
です。 配列内の「一致した」位置を保持する演算子変数:
Folder.findOneAndUpdate(
{ "_id": folderId, "permissions._id": permission._id },
{
"$set": {
"permissions.$": permission
}
},
function(err,doc) {
}
);
その.findOneAndUpdate()
メソッドは変更されたドキュメントを返すか、それ以外の場合は.update()
を使用できます ドキュメントを返す必要がない場合のメソッドとして。主な部分は、更新する配列の要素を「一致」させ、位置の$
と一致する「識別」を行うことです。 前述のとおり。
そしてもちろん、 $set
を使用しています のみになるように演算子 指定した要素は、実際には「ネットワーク経由」でサーバーに送信されます。これを「ドット表記」でさらに進めて、実際に更新する要素を指定するだけです。のように:
Folder.findOneAndUpdate(
{ "_id": folderId, "permissions._id": permission._id },
{
"$set": {
"permissions.$.role": permission.role
}
},
function(err,doc) {
}
);
つまり、これはMongoDBが提供する柔軟性であり、実際にドキュメントを更新する方法を非常に「ターゲット」にすることができます。
ただし、これが行うことは、「検証」やその他の「事前保存フック」など、「マングース」スキーマに組み込んだロジックを「バイパス」することです。これは、「最適な」方法がMongoDBの「機能」であり、その設計方法であるためです。マングース自体は、このロジックの「便利な」ラッパーになろうとしています。ただし、自分である程度の制御を行う準備ができている場合は、最適な方法で更新を行うことができます。
したがって、可能な場合は、データを「埋め込み」のままにし、参照モデルを使用しないでください。これにより、同時実行性について心配する必要がない単純な更新で、「親」アイテムと「子」アイテムの両方のアトミック更新が可能になります。おそらく、そもそもMongoDBを選択すべきだった理由の1つです。