はじめに
MongoDBを使用する場合、ほとんどの時間を何らかの方法でドキュメントの管理に費やします。新しいドキュメントを作成してコレクションに追加する場合でも、ドキュメントを取得する場合でも、データを更新する場合でも、古いアイテムを整理する場合でも、ドキュメントはMongoDBモデルの中心にあります。
このガイドでは、MongoDBドキュメントとは何かについて説明し、次に、ドキュメント中心の環境を管理するために知っておく必要のある一般的な操作について説明します。
MongoDBドキュメントとは何ですか?
MongoDBでは、データベースとコレクション内のすべてのデータがドキュメントに保存されます。コレクションはデフォルトで必要なスキーマを指定しないため、コレクション内のドキュメントには任意の複雑な構造を含めることができ、兄弟ドキュメントで使用される形式と一致する必要はありません。これにより、信じられないほどの柔軟性が提供され、アプリケーション要件の変化に応じてスキーマを有機的に開発できます。
MongoDBドキュメント自体は、JSONJavaScriptオブジェクト表記のバイナリ表現であるBSONデータシリアル化形式を使用します。これにより、プログラムでクエリおよび操作できる定義済みのデータ型を備えた組織化された構造が提供されます。
BSONドキュメントは、中括弧({}
)のペアで表されます。 )キーと値のペアが含まれています。 BSONでは、これらのデータカプレットはフィールドとして知られています。 およびその値 。フィールドが最初に来て、文字列で表されます。値は、任意の有効なBSONデータ型にすることができます。コロン(:
)フィールドをその値から分離します。カンマは、各フィールドと値のペアを互いに区切るために使用されます。
例として、MongoDBが理解できる有効なBSONドキュメントを次に示します。
{ _id: 80380, vehicle_type: "car", mileage: 7377.80, color: "blue", markets: [ "US", "UK" ], options: { transmission: "automatic", num_doors: 4, power_windows: true }}
ここでは、かなりの数のタイプを見ることができます:
-
_id
整数です -
vehicle_type
およびcolor
文字列です mileage
フロートですmarkets
文字列の配列ですoptions
文字列、整数、ブール値で構成される値を持つネストされたドキュメントが含まれています
この柔軟性により、ドキュメントはデータを保存するためのかなり柔軟な媒体です。新しいフィールドを簡単に追加でき、ドキュメントを相互に埋め込むことができ、構造の複雑さは保存されているデータと完全に一致します。
新しいドキュメントを作成する方法
新しいドキュメントを作成するには、作成したドキュメントを保存するデータベースに変更します。 school
を使用します この記事のデモンストレーション用のデータベース:
use school
また、ドキュメントを挿入するコレクションを選択することもできます。データベースと同様に、ドキュメントを挿入する場所にコレクションを明示的に作成する必要はありません。 MongoDBは、最初のデータが書き込まれるときに自動的に作成します。この例では、students
というコレクションを使用します 。
ドキュメントが保存される場所がわかったので、次のいずれかの方法を使用して新しいドキュメントを挿入できます。
insert()
の使用 メソッド
insert()
メソッドを使用すると、呼び出されたコレクションに1つ以上のドキュメントを挿入できます。
単一のドキュメントを挿入するには、コレクションでドキュメントを呼び出して、そのドキュメントをメソッドに渡します。ここでは、Ashleyという名前の学生用の新しいドキュメントを挿入します:
db.students.insert( { first_name: "Ashley", last_name: "Jenkins", dob: new Date("January 08, 2003"), grade_level: 8 })
WriteResult({ "nInserted" : 1 })
ドキュメントをinsert()
に渡す代わりに、同時に複数のドキュメントを挿入する場合 、ドキュメントの配列を渡します。ブライアンとリアという名前の学生向けに2つの新しいドキュメントを追加できます:
db.students.insert( [ { first_name: "Brian", last_name: "McMantis", dob: new Date("September 18, 2010"), grade_level: 2 }, { first_name: "Leah", last_name: "Drake", dob: new Date("October 03, 2009") } ])
BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 2, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ]})
一括書き込み操作を実行したため、戻り値はBulkWriteResult
です。 WriteResult
の代わりに 以前に見たオブジェクト。
insert()
この方法は柔軟性があり、多くのMongoDBドライバーでは廃止され、次の2つの方法が採用されています。
insertOne()
の使用 メソッド
insertOne()
メソッドを使用して、単一のドキュメントを挿入できます。 insert()
とは異なり この方法では、一度に1つのドキュメントしか挿入できないため、動作が少し予測しやすくなります。
構文は、insert()
を使用する場合と同じです。 単一のドキュメントを追加します。 Naomiという名前の別の生徒を追加できます:
db.students.insertOne( { first_name: "Naomi", last_name: "Pyani" })
{ "acknowledged" : true, "insertedId" : ObjectId("60e877914655cbf49ff7cb86")}
insert()
とは異なり 、insertOne()
メソッドは、いくつかの追加の有用な情報を含むドキュメントを返します。書き込みがクラスターによって確認されたことを確認し、提供しなかったためにドキュメントに割り当てられたオブジェクトIDが含まれます。
insertMany()
の使用 メソッド
複数のドキュメントを一度に挿入するシナリオをカバーするには、insertMany()
現在、この方法が推奨されています。 insert()
で複数のドキュメントを挿入する場合と同じです 、insertMany()
一連のドキュメントを取得します。
Jasmine、Michael、Toniという名前の3人の新しい生徒を追加できます:
db.students.insertMany( [ { first_name: "Jasmine", last_name: "Took", dob: new Date("April 11, 2011") }, { first_name: "Michael", last_name: "Rodgers", dob: new Date("February 25, 2008"), grade_level: 6 }, { first_name: "Toni", last_name: "Fowler" } ])
{ "acknowledged" : true, "insertedIds" : [ ObjectId("60e8792d4655cbf49ff7cb87"), ObjectId("60e8792d4655cbf49ff7cb88"), ObjectId("60e8792d4655cbf49ff7cb89") ]}
insertOne()
と同様 、insertMany()
書き込みを確認し、挿入されたドキュメントに割り当てられたIDを含む配列を提供するドキュメントを返します。
既存のドキュメントをクエリする方法
ドキュメントのクエリは、独自の記事を保証するかなり広範なトピックです。さまざまなタイプのドキュメントを取得するためのクエリを作成する方法の詳細については、MongoDB内のデータのクエリに関するガイドをご覧ください。
詳細は上記のリンク先の記事に残すのが最適ですが、少なくともMongoDBがドキュメントをクエリするために提供するメソッドについては説明できます。 MongoDBからドキュメントをフェッチする主な方法は、find()
を呼び出すことです。 問題のコレクションのメソッド。
たとえば、students
からすべてのドキュメントを収集するには 、find()
を呼び出すことができます 引数なし:
db.students.find()
{ "_id" : ObjectId("60e8743b4655cbf49ff7cb83"), "first_name" : "Ashley", "last_name" : "Jenkins", "dob" : ISODate("2003-01-08T00:00:00Z"), "grade_level" : 8 }{ "_id" : ObjectId("60e875d54655cbf49ff7cb84"), "first_name" : "Brian", "last_name" : "McMantis", "dob" : ISODate("2010-09-18T00:00:00Z"), "grade_level" : 2 }{ "_id" : ObjectId("60e875d54655cbf49ff7cb85"), "first_name" : "Leah", "last_name" : "Drake", "dob" : ISODate("2009-10-03T00:00:00Z") }{ "_id" : ObjectId("60e877914655cbf49ff7cb86"), "first_name" : "Naomi", "last_name" : "Pyani" }{ "_id" : ObjectId("60e8792d4655cbf49ff7cb87"), "first_name" : "Jasmine", "last_name" : "Took", "dob" : ISODate("2011-04-11T00:00:00Z") }{ "_id" : ObjectId("60e8792d4655cbf49ff7cb88"), "first_name" : "Michael", "last_name" : "Rodgers", "dob" : ISODate("2008-02-25T00:00:00Z"), "grade_level" : 6 }{ "_id" : ObjectId("60e8792d4655cbf49ff7cb89"), "first_name" : "Toni", "last_name" : "Fowler" }
出力を読みやすくするために、pretty()
をチェーンすることもできます find()
の後のメソッド :
db.<collection>.find().pretty()
{ "_id" : ObjectId("60e8743b4655cbf49ff7cb83"), "first_name" : "Ashley", "last_name" : "Jenkins", "dob" : ISODate("2003-01-08T00:00:00Z"), "grade_level" : 8}{ "_id" : ObjectId("60e875d54655cbf49ff7cb84"), "first_name" : "Brian", "last_name" : "McMantis", "dob" : ISODate("2010-09-18T00:00:00Z"), "grade_level" : 2}{ "_id" : ObjectId("60e875d54655cbf49ff7cb85"), "first_name" : "Leah", "last_name" : "Drake", "dob" : ISODate("2009-10-03T00:00:00Z")}{ "_id" : ObjectId("60e877914655cbf49ff7cb86"), "first_name" : "Naomi", "last_name" : "Pyani"}{ "_id" : ObjectId("60e8792d4655cbf49ff7cb87"), "first_name" : "Jasmine", "last_name" : "Took", "dob" : ISODate("2011-04-11T00:00:00Z")}{ "_id" : ObjectId("60e8792d4655cbf49ff7cb88"), "first_name" : "Michael", "last_name" : "Rodgers", "dob" : ISODate("2008-02-25T00:00:00Z"), "grade_level" : 6}{ "_id" : ObjectId("60e8792d4655cbf49ff7cb89"), "first_name" : "Toni", "last_name" : "Fowler"}
_id
各ドキュメントにフィールドが追加されました。 MongoDBには、一意の_id
が必要です コレクション内のドキュメントごとに。オブジェクトの作成時に提供しない場合は、追加されます。このIDを使用して、単一のオブジェクトを確実に取得できます:
db.students.find( { _id : ObjectId("60e8792d4655cbf49ff7cb89") })
{ "_id" : ObjectId("60e8792d4655cbf49ff7cb89"), "first_name" : "Toni", "last_name" : "Fowler" }
上記のリンク先の記事で、データをクエリするさまざまな方法について詳しく知ることができます。
既存のドキュメントを更新する方法
データベースの多くまたはほとんどのユースケースでは、データベース内の既存のデータを変更できる必要があります。新しい値を反映するためにフィールドを更新する必要がある場合や、既存のドキュメントが利用可能になったときに追加情報を追加する必要がある場合があります。
MongoDBは、いくつかの関連するメソッドを使用して既存のドキュメントを更新します。
-
updateOne()
:提供されたフィルターに基づいて、コレクション内の単一のドキュメントを更新します。 -
updateMany()
:提供されたフィルターに一致するコレクション内の複数のドキュメントを更新します。 -
replaceOne()
:提供されたフィルターに基づいて、コレクション内のドキュメント全体を置き換えます。
これらの各種類を使用して、さまざまなタイプの更新を実行する方法について説明します。
オペレーターの更新
ドキュメントを更新するための各方法を確認する前に、使用可能な更新演算子のいくつかを確認する必要があります。
-
$currentDate
:フィールドの値を、日付またはタイムスタンプタイプとして現在の日付に設定します。- 構文:
{ $currentDate: { <field>: <type>, ... } }
- 構文:
-
$inc
:フィールドの値を設定された量だけインクリメントします。- 構文:
{ $inc: { <field>: <amount>, ... } }
- 構文:
-
$min
:指定された値が現在の値よりも小さい場合、フィールドの値を更新します。- 構文:
{ $min: { <field>: <value>, ... } }
- 構文:
-
$max
:指定された値が現在の値より大きい場合、フィールドの値を更新します。- 構文:
{ $max: { <field>: <value>, ... } }
- 構文:
-
$mul
:フィールドの値に指定された数値を掛けて更新します。- 構文:
{ $mul: { <field>: <value>, ... } }
- 構文:
-
$rename
:フィールド名を新しい識別子に変更します。- 構文:
{ $rename: { <field>: <new_name>, ... } }
- 構文:
-
$set
:フィールドの値を指定された値に置き換えます。- 構文:
{ $set: { <field>: value, ... } }
- 構文:
-
$setOnInsert
:アップサート操作中に、新しいドキュメントが作成されている場合はフィールドの値を設定し、それ以外の場合は何もしません。- 構文:
{ $setOnInsert: { <field>: <value>, ... } }
- 構文:
-
$unset
:ドキュメントからフィールドを削除します。- 構文:
{ $unset: { <field>: "", ... } }
- 構文:
-
$
:クエリを満たす最初の配列要素のプレースホルダー。- 構文:
{ <update_operator>: {<array>.$: <value> } }
- 構文:
-
$[]
:クエリを満たすすべての配列要素のプレースホルダー。- 構文:
{ <update_operator>: { <array>.$[]: <value> } }
- 構文:
-
$addToSet
:すでに存在しない限り、配列に値を追加します。- 構文:
{ $addToSet: { <field>: <value>, ... } }
- 構文:
-
$pop
:配列の最初または最後の要素を削除します。- 構文:
{ $pop: { <field>: (-1 or 1), ... } }
- 構文:
-
$pull
:条件に一致する配列のすべての要素を削除します。- 構文:
{ $pull: { <field>: <condition>, ... } }
- 構文:
-
$push
:配列に値を追加します。- 構文:
{ $push: { <field>: <value>, ... } }
- 構文:
-
$pullAll
:指定されたすべての要素を配列から削除します。- 構文:
{ $pullAll: { <field>: [ <value>, ... ], ...} }
- 構文:
-
$each
:$addToSet
を変更します および$push
演算子を使用して、配列ではなく配列の各要素を単一の要素として追加します。- 構文:
{ <update_operator>: { <field>: { $each: [ <value>, ... ] }, ... } }
- 構文:
-
$position
:$each
とともに使用$push
の位置を指定します オペレーターはに挿入する必要があります。- 構文:
{ $push: { <field>: { $each: [ <value>, ... ], $position: <num> } } }
- 構文:
-
$slice
:$each
とともに使用 および$push
配列内の要素の総数を制限します。- 構文:
{ $push: { <field>: { $each: [ <value>, ... ], $slice: <num> } } }
- 構文:
-
$sort
:$each
とともに使用 および$push
配列要素を並べ替えます。- 構文:
{ $push: { <field>: { $each: [ <value>, ... ], $sort: <sort_order> } } }
- 構文:
これらのさまざまな更新演算子を使用すると、ドキュメントのさまざまなフィールドをさまざまな方法で更新できます。
コレクション内の単一のドキュメントを更新する
MongoDBのupdateOne()
メソッドは、コレクション内の単一のドキュメントを更新するために使用されます。このメソッドは、2つの必須の引数と、オプションの引数を指定するドキュメントを取ります。
最初の引数は、ドキュメントの選択に使用されるフィルター条件を指定するドキュメントです。 updateOne()
以降 メソッドは、コレクション内の最大1つのドキュメントを変更し、フィルター条件を満たす最初のドキュメントが使用されます。
2番目の引数は、実行する必要のある更新操作を指定します。上記の更新操作をここで指定して、一致したドキュメントの内容を変更できます。
3番目の引数は、メソッドの動作を変更するためのさまざまなオプションのドキュメントです。最も重要な潜在的な値は次のとおりです。
upsert
:フィルターが既存のドキュメントと一致しない場合は、新しいドキュメントを挿入することにより、操作をアップサート手順に変換します。collation
:操作に適用する必要がある言語固有のルールを定義するドキュメント。
例として、_id
でフィルタリングした単一の学生レコードを更新できます。 正しいドキュメントをターゲットにしていることを確認するためのフィールド。 grade_level
を設定できます 新しい値に:
db.students.updateOne( { _id: ObjectId("60e8792d4655cbf49ff7cb89") }, { $set: { grade_level: 3 } })
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
コレクション内の複数のドキュメントを更新する
MongoDBのupdateMany()
メソッドはupdateOne()
と同様に機能します メソッドですが、最初の一致後に停止するのではなく、指定されたフィルターに一致するすべてのドキュメントを更新します。
updateMany()
構文はupdateOne()
に正確に従います 構文なので、唯一の違いは操作の範囲です。
例として、subjects
の「composition」のすべてのインスタンスを「writing」に変更したい場合 teachers
の配列 コレクションドキュメントの場合、次のようなものを使用できます:
db.teachers.updateMany( { subject: "composition" }, { $set: { "subjects.$": "writing" } })
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }
ドキュメントをチェックする場合、「構成」の各インスタンスは「書き込み」に置き換えられているはずです:
db.teachers.find()
{ "_id" : ObjectId("60eddca65eb74f5c676f3baa"), "first_name" : "Nancy", "last_name" : "Smith", "subjects" : [ "vocabulary", "pronunciation" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bab"), "first_name" : "Ronald", "last_name" : "Taft", "subjects" : [ "literature", "grammar", "writing" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bac"), "first_name" : "Casey", "last_name" : "Meyers", "subjects" : [ "literature", "writing", "grammar" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bad"), "first_name" : "Rebecca", "last_name" : "Carrie", "subjects" : [ "grammar", "literature" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bae"), "first_name" : "Sophie", "last_name" : "Daggs", "subjects" : [ "literature", "writing", "grammar", "vocabulary", "pronunciation" ] }
ドキュメントの置き換え
replaceOne()
メソッドはupdateOne()
と同様に機能します メソッドですが、個々のフィールドを更新するのではなく、ドキュメント全体を置き換えます。構文は前の2つのコマンドと同じです。
たとえば、ナンシースミスが学校を辞め、彼女を文学を教えるクララニューマンという名前の教師に置き換える場合は、次のように入力できます。
db.teachers.replaceOne( { $and: [ { first_name: "Nancy" }, { last_name: "Smith" } ] }, { first_name: "Clara", last_name: "Newman", subjects: [ "literature" ] })
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
一致したドキュメントが削除され、指定されたドキュメントが置き換えられたことがわかります。
db.teachers.find()
{ "_id" : ObjectId("60eddca65eb74f5c676f3baa"), "first_name" : "Clara", "last_name" : "Newman", "subjects" : [ "literature" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bab"), "first_name" : "Ronald", "last_name" : "Taft", "subjects" : [ "literature", "grammar", "writing" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bac"), "first_name" : "Casey", "last_name" : "Meyers", "subjects" : [ "literature", "writing", "grammar" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bad"), "first_name" : "Rebecca", "last_name" : "Carrie", "subjects" : [ "grammar", "literature" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bae"), "first_name" : "Sophie", "last_name" : "Daggs", "subjects" : [ "literature", "writing", "grammar", "vocabulary", "pronunciation" ] }
ドキュメントを削除する方法
コレクションからドキュメントを削除することも、ドキュメントのライフサイクルの一部です。ドキュメントを削除するには、deleteOne()
を使用できます またはdeleteMany()
メソッド。構文は同じで、操作するドキュメントの数だけが異なります。
ほとんどの場合、これらの方法のいずれかを使用してドキュメントを削除するために必要なのは、削除するドキュメントを選択する方法を指定するフィルタードキュメントを提供することだけです。 deleteOne()
deleteMany()
が生成する間、メソッドは最大で1つのドキュメントを削除します(フィルターが生成する一致の数に関係なく) メソッドは、フィルター条件に一致するすべてのドキュメントを削除します。
たとえば、1人の生徒を削除するには、_id
を指定します。 それらを明示的に一致させるには:
db.students.deleteOne({ _id: ObjectId("60e8792d4655cbf49ff7cb87")})
{ "acknowledged" : true, "deletedCount" : 1 }
学年レベルが割り当てられていない生徒を削除する場合は、deleteMany()
を使用できます。 代わりに方法:
db.students.deleteMany({ grade_level: { $eq: null }})
{ "acknowledged" : true, "deletedCount" : 2 }
チェックすると、残りのすべての生徒に学年レベルが割り当てられていることがわかります。
db.students.find()
{ "_id" : ObjectId("60e8743b4655cbf49ff7cb83"), "first_name" : "Ashley", "last_name" : "Jenkins", "dob" : ISODate("2003-01-08T00:00:00Z"), "grade_level" : 8 }{ "_id" : ObjectId("60e875d54655cbf49ff7cb84"), "first_name" : "Brian", "last_name" : "McMantis", "dob" : ISODate("2010-09-18T00:00:00Z"), "grade_level" : 2 }{ "_id" : ObjectId("60e8792d4655cbf49ff7cb88"), "first_name" : "Michael", "last_name" : "Rodgers", "dob" : ISODate("2008-02-25T00:00:00Z"), "grade_level" : 6 }{ "_id" : ObjectId("60e8792d4655cbf49ff7cb89"), "first_name" : "Toni", "last_name" : "Fowler", "grade_level" : 3 }
結論
ドキュメントの作成、クエリ、更新、削除の方法を学ぶことで、MongoDB内のドキュメントを日常的に効果的に管理するために必要なスキルを身に付けることができます。さまざまなドキュメントと収集方法、および情報の照合と変更を可能にする演算子に精通することで、データベースシステムが理解できる複雑な考えを表現できます。