MongoDB CRUD操作まとめ

スポンサーリンク

MongoDBのCRUD(Create, Read, Update, Delete)操作についてまとめます。

前提

公式ドキュメント

参考になる公式ドキュメントを以下に示します。

動作確認済環境

  • Rocky Linux 8.6
  • MongoDB Server 6.0.2

公式ドキュメントの読み方

CRUD操作はツール毎に使用感が異なります。本書はmongosh(MongoDB shell)を使う場合を示しますが、公式ドキュメントではMongoDB shell, Compass(GUIツール), C#, Go, Java(Async), Java(Sync), Motor, Node.jsの操作例が示されています。

公式ドキュメント右上の「Select your language」プルダウンを操作する事で、お好みのツールの使用方法を調査する事ができます。

img 001

CRUD操作

Create

1件Create

1件Createの操作をするには、InsertOneを使用します。操作例は以下の通りです。

db.createCollection('inventory')

db.inventory.insertOne(
   { _id: 0, item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
)

想定通りのレコードが追加された事を確認します。

test> db.inventory.find()
[
  {
    _id: 0,
    item: 'canvas',
    qty: 100,
    tags: [ 'cotton' ],
    size: { h: 28, w: 35.5, uom: 'cm' }
  }
]

複数件Create

複数件Createの操作をするには、InsertManyを使用します。操作例は以下の通りです。

InsertManyで登録されたデータは原子性(Atomicity)が保証されます。

db.inventory.insertMany([
   { _id: 1, item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
   { _id: 2, item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
])

想定通りのレコードが追加された事を確認します。

test> db.inventory.find()
[
  {
    _id: 0,
    item: 'canvas',
    qty: 100,
    tags: [ 'cotton' ],
    size: { h: 28, w: 35.5, uom: 'cm' }
  },
  {
    _id: 1,
    item: 'journal',
    qty: 25,
    tags: [ 'blank', 'red' ],
    size: { h: 14, w: 21, uom: 'cm' }
  },
  {
    _id: 2,
    item: 'mat',
    qty: 85,
    tags: [ 'gray' ],
    size: { h: 27.9, w: 35.5, uom: 'cm' }
  }
]
test> 

PrimaryKey(_id)省略時の挙動

insert処理をする時はPrimaryKey(_id)を省略する事もできます。PrimaryKey(_id)を省略した場合は、ObjectIDがPrimaryKey(_id)にセットされます。

以下に操作例を示します。確かに、PrimaryKey(_id)がObjectIDとなる事を確認できます。

test> db.inventory.insertOne(
...    { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
... )
{
  acknowledged: true,
  insertedId: ObjectId("634d3bbb05cb7e4fd9c0fee9")
}
test> db.inventory.find( { item: "mousepad" } )
[
  {
    _id: ObjectId("634d3bbb05cb7e4fd9c0fee9"),
    item: 'mousepad',
    qty: 25,
    tags: [ 'gel', 'blue' ],
    size: { h: 19, w: 22.85, uom: 'cm' }
  }
]
test> 

Read

データ準備

動作確認用のデータを準備します。

db.inventory.drop()
db.createCollection('inventory')

db.inventory.insertMany([
   { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
   { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
   { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
   { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
   { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);

全件検索

全件検索するには以下のような操作をします。

db.inventory.find()

条件指定検索

条件指定で検索する場合は、findの引数に検索条件を与えます。書式は以下の通りです。

db.inventory.find({ <field1>: <value1>, ... })

単純な完全一致検索ならば、以下のように操作します。

db.inventory.find( { status: "D" } )

大小比較ならば、以下のように操作します。

db.inventory.find( { qty: { $lt: 50 } } )

含まれるかどうかの操作(SQL文のIN句)ならば、以下のように操作します。

db.inventory.find( { status: { $in: [ "A", "D" ] } } )

AND条件

複数条件を使用しAND条件で検索したい場合は、以下のように操作します。

db.inventory.find( { status: "A", qty: { $lt: 30 } } )

OR条件

複数条件を使用しOR条件で検索したい場合は、以下のように操作します。

db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )

AND条件とOR条件を併用する場合は、以下のように操作します。

db.inventory.find( {
     status: "A",
     $or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
} )

表示フィールドの絞り込み

全てのフィールドが表示されるのがわずらわしく、一部フィールドのみを表示したい事もあるかもしれません。そのような場合は、SQL文のSELECT句相当の操作もできます。findメソッドに以下のような引数を与えます。

find({<検索条件1>}, {<検索条件2>}, ... {<表示条件>})

statusがAのレコードについてitem, qtyのみを表示させるならば、以下のように操作します。1またはtrueを指定したフィールドが表示対象になり、0またはfalseを指定したフィールドが非表示になります。_idはデフォルトで表示されますので、もし_idを非表示にしたいならば「_id: 0」と指定します。

test> db.inventory.find( {status: "A"}, { item: 1, qty: 1, _id: 0 } )
[
  { item: 'journal', qty: 25 },
  { item: 'notebook', qty: 50 },
  { item: 'postcard', qty: 45 }
]
test> 

全件についてitem, qtyのみを表示させるならば、以下のように操作します。

test> db.inventory.find( {}, { item: 1, qty: 1, _id: 0 } )
[
  { item: 'journal', qty: 25 },
  { item: 'notebook', qty: 50 },
  { item: 'paper', qty: 100 },
  { item: 'planner', qty: 75 },
  { item: 'postcard', qty: 45 }
]
test> 

Update

データ準備

動作確認用のデータを準備します。

db.inventory.drop()
db.createCollection('inventory')

db.inventory.insertMany( [
   { item: "canvas", qty: 100, size: { h: 28, w: 35.5, uom: "cm" }, status: "A" },
   { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
   { item: "mat", qty: 85, size: { h: 27.9, w: 35.5, uom: "cm" }, status: "A" },
   { item: "mousepad", qty: 25, size: { h: 19, w: 22.85, uom: "cm" }, status: "P" },
   { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "P" },
   { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
   { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
   { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" },
   { item: "sketchbook", qty: 80, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
   { item: "sketch pad", qty: 95, size: { h: 22.85, w: 30.5, uom: "cm" }, status: "A" }
] );

1件Update

MongoDBでレコードを更新するには、updateOne, updateMany, replaceOneなどのメソッドを使います。 これらメソッドに与える引数は以下のように指定します。update operatorには更新対象を絞り込む条件(WHRER句相当)を記述します。

{
  <update operator>: { <field1>: <value1>, ... },
  <update operator>: { <field2>: <value2>, ... },
  ...
}

canvasを変更する操作を例示します。まずは、変更前のレコードを確認します。変更前は数量(qty)は100で最終更新時刻も記録されていません。

test> db.inventory.find({item: "canvas"})
[
  {
    _id: ObjectId("635102fd692a7c235c919914"),
    item: 'canvas',
    qty: 100,
    size: { h: 28, w: 35.5, uom: 'cm' },
    status: 'A'
  }
]
test> 

canvasの数量(qty)を40に変更し最終更新時刻を付与する操作をします。

db.inventory.updateOne(
   { item: "canvas" },
   {
     $set: { qty: 40 },
     $currentDate: { lastModified: true }
   }
)

数量(qty)が40に変わり最終更新時刻が付与された事を確認できます。

test> db.inventory.find({item: "canvas"})
[
  {
    _id: ObjectId("635102fd692a7c235c919914"),
    item: 'canvas',
    qty: 40,
    size: { h: 28, w: 35.5, uom: 'cm' },
    status: 'A',
    lastModified: ISODate("2022-10-20T08:31:50.795Z")
  }
]
test> 

複数件Update

数量(qty)が30未満の商品について、一括で変更する操作をします。まずは、変更前のレコードを確認します。変更前は単位(size.uom)をセンチ(cm)で、statusはAとPが混在しています。

test> db.inventory.find({qty: { $lt: 30 } })
[
  {
    _id: ObjectId("635102fd692a7c235c919915"),
    item: 'journal',
    qty: 25,
    size: { h: 14, w: 21, uom: 'cm' },
    status: 'A'
  },
  {
    _id: ObjectId("635102fd692a7c235c919917"),
    item: 'mousepad',
    qty: 25,
    size: { h: 19, w: 22.85, uom: 'cm' },
    status: 'P'
  }
]
test> 

数量(qty)が30未満の商品について、単位(size.uom)をセンチ(cm)からインチ(in)に変更しstatusをPに変更する操作をします。

db.inventory.updateMany(
   { "qty": { $lt: 30 } },
   {
     $set: { "size.uom": "in", status: "P" }
   }
)

想定通りの変更がなされた事を確認します。

test> db.inventory.find({qty: { $lt: 30 } })
[
  {
    _id: ObjectId("635102fd692a7c235c919915"),
    item: 'journal',
    qty: 25,
    size: { h: 14, w: 21, uom: 'in' },
    status: 'P'
  },
  {
    _id: ObjectId("635102fd692a7c235c919917"),
    item: 'mousepad',
    qty: 25,
    size: { h: 19, w: 22.85, uom: 'in' },
    status: 'P'
  }
]
test> 

1件Replace

前述のupdateメソッドは指定したフィールドのみが更新される操作です。これに対し、replaceメソッドは全てのフィールドが更新される操作です。言い換えれば、指定していないフィールドは削除されます。それでは実際の例を観察してみましょう。

変更前のpaperは以下のような状態です。変更前はsizeフィールドとstatusフィールドが存在する事を覚えていてください。

test> db.inventory.find({item: "paper"})
[
  {
    _id: ObjectId("635102fd692a7c235c919919"),
    item: 'paper',
    qty: 100,
    size: { h: 8.5, w: 11, uom: 'in' },
    status: 'D'
  }
]
test>

paperをreplaceします。

db.inventory.replaceOne(
   { item: "paper" },
   { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] }
)

変更後のpaperを以下に示します。replaceOneメソッドにsizeフィールドやstatusは含まれていないため、更新後はsizeフィールドが消えている事が読み取れます。代わりに、replaceOneメソッドで指定したinstockフィールドが追加されている事も読み取れます。

test> db.inventory.find({item: "paper"})
[
  {
    _id: ObjectId("635102fd692a7c235c919919"),
    item: 'paper',
    instock: [ { warehouse: 'A', qty: 60 }, { warehouse: 'B', qty: 40 } ]
  }
]
test> 

Delete

データ準備

動作確認用のデータを準備します。

db.inventory.drop()
db.createCollection('inventory')

db.inventory.insertMany( [
   { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
   { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "P" },
   { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
   { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
   { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" },
] );

1件Delete

notebookを削除する操作例を示します。それでは変更前の全件を確認します。変更前はnotebookが存在します。

test> db.inventory.find( {}, { item: 1, qty: 1, _id: 0 } )
[
  { item: 'journal', qty: 25 },
  { item: 'notebook', qty: 50 },
  { item: 'paper', qty: 100 },
  { item: 'planner', qty: 75 },
  { item: 'postcard', qty: 45 }
]
test> 

notebookを削除します。

db.inventory.deleteOne( { item: 'notebook' } )

notebookが削除された事を確認します。

test> db.inventory.find( {}, { item: 1, qty: 1, _id: 0 } )
[
  { item: 'journal', qty: 25 },
  { item: 'paper', qty: 100 },
  { item: 'planner', qty: 75 },
  { item: 'postcard', qty: 45 }
]
test>

複数件Delete

数量(qty)が50件未満のレコードを削除する操作例を示します。それでは変更前の全件を確認します。変更前はjournalとpostcardが存在します。

test> db.inventory.find( {}, { item: 1, qty: 1, _id: 0 } )
[
  { item: 'journal', qty: 25 },
  { item: 'paper', qty: 100 },
  { item: 'planner', qty: 75 },
  { item: 'postcard', qty: 45 }
]
test>

数量(qty)が50件未満のレコードを削除します。

db.inventory.deleteMany( {qty: { $lt: 50 } } )

journalとpostcardが削除された事を確認します。

test> db.inventory.find( {}, { item: 1, qty: 1, _id: 0 } )
[ { item: 'paper', qty: 100 }, { item: 'planner', qty: 75 } ]
test> 

フィールド削除

レコードそのものではなく、レコードの1つのフィールドを削除するには前述のreplaceOneを使うと良いでしょう。

繰り返しになりますが、再度の動作確認をします。変更前のpaperの状態を確認します。sizeやstatusのフィールドが存在します。

test> db.inventory.find( {item: "paper"} )
[
  {
    _id: ObjectId("63510cb0692a7c235c919920"),
    item: 'paper',
    qty: 100,
    size: { h: 8.5, w: 11, uom: 'in' },
    status: 'D'
  }
]
test> 

size, statusのフィールドを削除します。

db.inventory.replaceOne(
   { item: "paper" },
   { item: "paper", qty: 100 }
)

想定通りのフィールド削除がなされて事を確認します。

test> db.inventory.find( {item: "paper"} )
[
  {
    _id: ObjectId("63510cb0692a7c235c919920"),
    item: 'paper',
    qty: 100
  }
]
test> 
タイトルとURLをコピーしました