MongoDB
 Computer >> コンピューター >  >> プログラミング >> MongoDB

MongoDBで複合ユニークインデックスを作成する方法(createIndexの使い方)

MongoDBにおける複合ユニークインデックスとは

MongoDBでは、createIndex()メソッドを使うことで、複数のフィールドを組み合わせた「複合インデックス」を作成できます。さらにunique: trueオプションを指定すると、そのフィールドの組み合わせが重複しないように一意制約(ユニーク制約)を設けることが可能です。

本記事では、実際のコマンド例を通じて、複合ユニークインデックスの作成方法と、重複データ挿入時の挙動について解説します。

複合ユニークインデックスの作成

まずはcreateIndex()を使用して、「StudentName」と「StudentAge」の2つのフィールドに対して複合ユニークインデックスを作成します。

> db.compoundIndexDemo.createIndex({"StudentName":1,"StudentAge":1},{unique:true});
{
    "createdCollectionAutomatically" : true,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}

このコマンドでは、コレクションが存在しない場合は自動的に作成され(createdCollectionAutomatically: true)、デフォルトの_idインデックスに加えて新しい複合インデックスが追加されます(numIndexesAfter: 2)。

ドキュメントの挿入と重複チェック

次に、作成したコレクションにドキュメントを挿入していきます。まずは同じ名前「Chris」を持つドキュメントをいくつか登録してみましょう。

> db.compoundIndexDemo.insertOne({"StudentName":"Chris"});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e084c1d25ddae1f53b62207")
}
> db.compoundIndexDemo.insertOne({"StudentName":"Chris","StudentAge":23});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e084c5625ddae1f53b62209")
}
> db.compoundIndexDemo.insertOne({"StudentName":"Chris","StudentAge":22});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e084c5b25ddae1f53b6220a")
}

ここまでの挿入は成功しています。「Chris」という名前は重複していますが、年齢が異なる(または年齢フィールド自体が存在しない)ため、名前と年齢の組み合わせとしては一意になっているからです。

重複データ挿入時のエラー

しかし、すでに存在する「StudentName: Chris」「StudentAge: 23」の組み合わせと全く同じドキュメントを挿入しようとすると、一意制約違反によりエラーが発生します。

> db.compoundIndexDemo.insertOne({"StudentName":"Chris","StudentAge":23});
2019-12-29T12:19:02.225+0530 E QUERY [js] WriteError: E11000 duplicate key error collection: web.compoundIndexDemo index: StudentName_1_StudentAge_1 dup key: { : "Chris", : 23.0 } :
WriteError({
    "index" : 0,
    "code" : 11000,
    "errmsg" : "E11000 duplicate key error collection: web.compoundIndexDemo index: StudentName_1_StudentAge_1 dup key: { : \"Chris\", : 23.0 }",
    "op" : {
        "_id" : ObjectId("5e084c5e25ddae1f53b6220b"),
        "StudentName" : "Chris",
        "StudentAge" : 23
    }
})
WriteError@src/mongo/shell/bulk_api.js:461:48
Bulk/mergeBatchResults@src/mongo/shell/bulk_api.js:841:49
Bulk/executeBatch@src/mongo/shell/bulk_api.js:906:13
Bulk/this.execute@src/mongo/shell/bulk_api.js:1150:21
DBCollection.prototype.insertOne@src/mongo/shell/crud_api.js:252:9
@(shell):1:1

エラーコードE11000(duplicate key error)は、ユニークインデックスに違反するキーが挿入されたことを示しています。エラーメッセージ内のdup key: { : "Chris", : 23.0 }を見ると、どのキーの組み合わせが重複したのかを確認できます。

登録済みドキュメントの確認

最後に、find()メソッドを使ってコレクション内のすべてのドキュメントを表示してみます。

> db.compoundIndexDemo.find().pretty();

実行結果は以下の通りです。

{ "_id" : ObjectId("5e084c1d25ddae1f53b62207"), "StudentName" : "Chris" }
{
        "_id" : ObjectId("5e084c5625ddae1f53b62209"),
        "StudentName" : "Chris",
        "StudentAge" : 23
}
{
    "_id" : ObjectId("5e084c5b25ddae1f53b6220a"),
    "StudentName" : "Chris",
    "StudentAge" : 22
}

このように、重複エラーが発生したドキュメントは挿入されておらず、正常に挿入された3件のドキュメントのみが格納されていることがわかります。

まとめ

複合ユニークインデックスを利用することで、単一フィールドではなく複数フィールドの組み合わせに対して一意性を保証できます。これは「同じユーザー名でも異なる属性なら許可したいが、完全な重複は防ぎたい」といったケースで非常に有効です。データ整合性を保ちたい場面では、ぜひ活用してみてください。

  1. MongoDBのsave()メソッドで変数の値を設定・保存する方法

    MongoDBでsave()メソッドを使って変数の値を設定・保存するには、db.コレクション名.save(変数名)という形式を使用します。「変数名」の部分には、あらかじめ定義しておいた任意の変数を指定します。ここでは、実際のコード例を交えながら、変数に格納したドキュメントをsave()メソッドでコレクションに保存する手順を解説します。変数の作成まず、保存したいドキュメントを変数として定義しましょう。以下の例では、「Info」という変数に、名前・国名・プロジェクト詳細(配列形式)を含むドキュメントを作成しています。> var Info={Name:David, ... CountryNam

  2. MongoDBの集約(Aggregation)で特定のフィールド値を持つドキュメントを取得する方法

    特定の条件に一致するドキュメントを取得したい場合には、aggregate() メソッドを使用します。ここでは、フィールド「Age」の値が「21」であるドキュメントを取得するケースを例に解説します。 サンプルコレクションの作成 まずは、ドキュメントを含むコレクションを作成しましょう。 > db.demo685.insertOne( ... { ... details: ... [ ... { ... Name:Chris, ... Age:21 ... }, ..