MongoDB でのアップサート
- 
          
            MongoDB の upsertクエリ
- 
          
            update()メソッドでupsertクエリを使用する
- 
          
            findAndModify()メソッドでupsertクエリを使用する
- 
          
            upsertをサポートするその他のメソッド
 
MongoDB では、upsert はコマンド update と insert を組み合わせたものです。 update() および findAndModify() 操作で使用できます。
MongoDB の upsert クエリ
    
upsert は単一のブール値パラメーターを取ります。 これがTRUEに設定されていて、クエリ ドキュメントが見つかった場合、ドキュメントが更新されます。 見つからない場合は、コレクションに新しいドキュメントが挿入されます。
構文:
upsert: <boolean>
update() メソッドで upsert クエリを使用する
次の employee 用のドキュメントがあるとします。 ドキュメントを表示するには、Mongosh または MongoCLI で次のコマンドを入力します (データベースに正常に接続した後)。
> db.employee.find().pretty()
{"_id":1,   "name":"Alice"}
{"_id":2,   "name":"Bob"}
ここで、find() はドキュメントまたはオブジェクトの検索に使用されます。 パラメータを渡すこともできます。
たとえば、find({"_id":1}) と書くと、ID が 1 のオブジェクトのみが返されます。 pretty() は出力を適切な形式で出力するためのものです。
さて、次のように更新しようとすると:
> db.employee.update({_id:5},{name: "Jhon"})
WriteResult({"nMatched": 0,  "nUpserted": 0, "nModified": 0})
WriteResult からわかるように、ドキュメントは更新されていません。 ここで、TRUE 値で upsert オプションを試してください。
名前を検索して更新したいとしましょう。 たとえば、upsert オプションを使用して、すべての名前 Sam を Samuel に更新したいとします。
クエリは次のようになります。
> db.employee.update({name:"Sam"},{name: "Samuel"})
WriteResult({
    "nMatched": 0,  
    "nUpserted": 1, 
    "nModified": 0,
    "_id": ObjectId("67874504aed8aee9986")
})
>
ここでは、upserted の値が 1 であることがわかります。 Sam という名前に一致するものがないため、一意の _id を持つエンティティを作成しました。
ここで、employee の下にあるすべてのエンティティを表示する場合は、次のクエリを実行できます。
> db.employee.find().pretty()
{"_id":1,   "name":"Alice"}
{"_id":2,   "name":"Bob"}
{"_id":ObjectId("67874504aed8aee9986"),   "name":"Samuel"}
>
findAndModify() メソッドで upsert クエリを使用する
このメソッドは update() メソッドと同じように機能しますが、findAndModify は最初に一致したオブジェクトのみを更新しますが、update は一致したすべてのエンティティを変更します。
id が 3 に等しい新しいフィールドを追加するとします。 次のように書きます。
db.employee.findAndModify({query: {_id:3}, update:{$inc: {salary: 1500}}, upsert: true})
null
>
存在しなかったため、null を返します。
すべてのエンティティを表示すると、upsert が TRUE に設定されているため、新しいオブジェクトがドキュメントに追加されていることがわかります。 IDが3で給与が1500の新しいエンティティが追加されました。
> db.employee.find().pretty()
{"_id":1,   "name":"Alice"}
{"_id":2,   "name":"Bob"}
{"_id":ObjectId("67874504aed8aee9986"),   "name":"Samuel"}
{"_id":5,   "salary":"1500"}
upsert をサポートするその他のメソッド
次のメソッドでも upsert オプションを使用できます。
- updateOne()
- replaceOne()
詳細については、この ブログ をご覧ください。 また、MongoDB の 公式ドキュメント もあります。
