MongoDB でのアップサート

Shihab Sikder 2023年6月20日
  1. MongoDB の upsert クエリ
  2. update() メソッドで upsert クエリを使用する
  3. findAndModify() メソッドで upsert クエリを使用する
  4. upsert をサポートするその他のメソッド
MongoDB でのアップサート

MongoDB では、upsert はコマンド updateinsert を組み合わせたものです。 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 オプションを使用して、すべての名前 SamSamuel に更新したいとします。

クエリは次のようになります。

> 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 を返します。

すべてのエンティティを表示すると、upsertTRUE に設定されているため、新しいオブジェクトがドキュメントに追加されていることがわかります。 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 オプションを使用できます。

  1. updateOne()
  2. replaceOne()

詳細については、この ブログ をご覧ください。 また、MongoDB の 公式ドキュメント もあります。

著者: Shihab Sikder
Shihab Sikder avatar Shihab Sikder avatar

I'm Shihab Sikder, a professional Backend Developer with experience in problem-solving and content writing. Building secure, scalable, and reliable backend architecture is my motive. I'm working with two companies as a part-time backend engineer.

LinkedIn Website