MongoDBのupdateで1クエリでsetやunsetなど複数の更新を行う方法

1 min読了の目安(約1500字TECH技術記事

概要

MongDBでは条件に指定したドキュメントを更新できる、updateを行うクエリがあります。updateの際は、指定したフィールドに値をセットするsetや指定したフィールドを削除できるunsetなど複数の種類があります。あまり使うケースが無いかもしれませんが、このsetやunsetを1クエリで同時に行う方法を書きます。

前提

MongoDBにはupdateのクエリが何種類かあるのですが、今回は1ドキュメントを対象に更新するupdateOneで解説します。updateOneのクエリの仕様はこちらのドキュメントを参考にしてください。また、更新内容の種類についてはこちらを参考にしてください。
オプションの項目を割愛すると、1引数目に条件、2引数目に更新内容を設定します。以下がRubyで、クエリ発行した場合のサンプルソースです。 userコレクションに対しnamestatusを更新することを例としています。

def self.login_history_update(id, name, status)
  db = Mongoid::Clients.default
  user_collection = db[:users]
  user_collection.update_one(
    { '_id' => id },
    { '$set' => {
      'name' => name,
      'status' => status
    } }
  )
end

また、MongoDBのデータ構造を解説している記事について、MongoDB超入門が分かりやすいので、ご参考ください。

対応

対応としてはこちらのStackOverflowの記事にある通り、2個目の引数のオブジェクトに複数の更新内容(記事中だとsetとunset)を含めることができます。例えば、上記に挙げた実装サンプルに対しtemp_passwordというフィールドの削除を加えた場合、以下のような実装になります。

def self.login_history_update(id, name, status)
  db = Mongoid::Clients.default
  user_collection = db[:users]
  user_collection.update_one(
    { '_id' => id },
    {
      '$set' => {
        'name' => name,
        'status' => status
      },
      '$unset' => {
        'temp_password' => ''
      }
    }
  )
end