[MongoDB] Array field から特定の要素を削除する $pull と $pullAll

Mongoose で document の Array field から特定の要素のみ削除したい場合は、MongoDB の $pull もしくは $pullAll オペレーターを利用するのが良さそうです。

MongoDB | モンゴディービー

MongoDB $pull, $pullAll の使い方

$pull のサンプルコード

以下のような articles collection にデータがあるという前提で、

> db.articles.find()
{
  "_id": ObjectId("5b6d8b9e7e646a3119136780"),
  "editors": [
    ObjectId("5b6d8b9e7e646a311913677c"),
    ObjectId("5b6d8b9e7e646a311913677d"),
    ObjectId("5b6d8b9e7e646a311913677e"),
    ObjectId("5b6d8b9e7e646a311913677f")
  ]
}
{
  "_id" : ObjectId("5b6d8d417e646a3119136782"),
  "editors" : [
    ObjectId("5b6d8b9e7e646a311913677d"),
    ObjectId("5b6d8d417e646a3119136781")
  ]
}

$pull オペレーターを使って update クエリを実行すると、

var deletedUserId = ObjectId("5b6d8b9e7e646a311913677d")
 
db.articles.update(
  {},
  {
    $pull : {
      editors : deletedUserId
    }
  },
  {
    multi: true
  }
)

editors から deletedUserId の要素が削除できました。

> db.articles.find()
{
  "_id": ObjectId("5b6d8b9e7e646a3119136780"),
  "editors": [
    ObjectId("5b6d8b9e7e646a311913677c"),
    ObjectId("5b6d8b9e7e646a311913677e"),
    ObjectId("5b6d8b9e7e646a311913677f")
  ]
}

$pullAll のサンプルコード

続けて $pullAll オペレーターを使って update クエリを実行すると、

var deletedUserIds = [
  ObjectId("5b6d8b9e7e646a311913677e"),
  ObjectId("5b6d8b9e7e646a311913677f")
]
 
db.articles.update(
  {},
  {
    $pullAll: {
      editors: deletedUserIds
    }
  },
  {
    multi: true
  }
)

editors から deletedUserIds の要素が削除できました。

> db.articles.find()
{
  "_id": ObjectId("5b6d8b9e7e646a3119136780"),
  "editors": [
    ObjectId("5b6d8b9e7e646a311913677c")
  ]
}
{
  "_id": ObjectId("5b6d8d417e646a3119136782"),
  "editors": [
    ObjectId("5b6d8b9e7e646a311913677d"),
    ObjectId("5b6d8d417e646a3119136781")
  ]
}

$pull, $pullAll のユースケースは?

MongoDB の $pull, $pullAll を使うケースは、ユーザーの退会により editors データを物理削除したときに articles.editors などの reference が保存されている field を綺麗にしたいというようなときに有効です。

以上、MongoDB の Array field から特定の要素を削除したい、現場からお送りしました。