Docs Menu
Docs Home
/ /

Unique Indexes

ユニークインデックスにより、インデックス フィールドに重複する値が保存されなくなり、特定のフィールドに値が最大 1 回表示されるようになります。一意の複合インデックスを使用すると、インデックスキー値の任意の組み合わせが最大 1 回だけ表示されます。デフォルトでは、 MongoDB はコレクションの作成 中に _idフィールドにユニークインデックスを作成します。

でホストされる配置用MongoDB Atlas に、 一意のインデックスを UI に作成して管理 できます 。

ユニークインデックスを作成するには、unique オプションを true に設定した状態で、db.collection.createIndex() メソッドを使用します。

db.collection.createIndex( <key and index type specification>, { unique: true } )

たとえば、 usersコレクションのemailフィールドに一意のインデックスを作成するには、 mongoshで次の操作を使用します。

db.users.createIndex( { "email": 1 }, { unique: true } )

複合インデックスにも一意の制約を適用できます。 一意の複合インデックスでは、インデックス キー値の組み合わせに一意であることが強制されます。

たとえば、 usersコレクションのnameemail 、およびpasswordフィールドに一意のインデックスを作成するには、 mongoshで次の操作を使用します。

db.users.createIndex( { name: 1, email: 1, password: 1 }, { unique: true } )

作成されたインデックスでは、nameemailpassword の値の組み合わせは必然的に一意になります。

次のとおり、ユニークな複合マルチキー インデックスを emailname に作成します。

db.users.createIndex( { "email": 1, "name": 1 }, { unique: true } )

ユニークインデックスを使用すると、emailname の値の 組み合わせが必然的に一意になるため、次のドキュメントをコレクションに挿入できます。

db.users.insertMany( [
{ name: "Catelyn Stark", email: [ "catelyn@gameofthron.es", "sean_bean@gameofthron.es" ], password: "$2b$12$hash2" },
{ name: "Arya Stark", email: [ "catelyn@gameofthron.es" ], password: "$2b$12$hash3" }
] )

両方のドキュメントで"catelyn@gameofthron.es" email配列に が含まれていても、 フィールドと各メール値の組み合わせは一意であるため、操作は成功します。name

Tip

MongoDBは、コレクションにユニーク制約に違反するデータが既に含まれている場合、指定されたインデックス フィールドにユニークインデックスを作成できません。

ハッシュされたインデックスにユニーク制約を指定することはできません。

レプリカセットとシャーディングされたクラスターでローリング手順を使用してユニークインデックスを作成するには、その手順の実行中にコレクションへの書込みをすべて停止する必要があります。書込みを停止できない場合は、ローリング手順は使用せず、代わりに、次のいずれかの方法でコレクションにユニークインデックスを構築します。

ユニーク制約は、コレクション内のドキュメントに個別に適用されます。具体的には、個別のドキュメントでインデックス キーの値が同じになることはありません。

この制約は個別のドキュメントに適用されるため、ユニークマルチキー インデックスの場合、ドキュメントに含まれる配列要素によって、そのドキュメントのインデックス キー値と別のドキュメントのインデックス キー値が重複していない限り、インデックス キー値の反復につながることがあります。この場合、反復されるインデックスエントリはインデックスに 1 度のみ挿入されます。

例、emailname に一意の複合マルチキーインデックスを作成します。

db.users.createIndex( { "email": 1, "name": 1 }, { unique: true } )

ユニークインデックスを使用すると、インデックスキー値が { "email": "arya@winterfell.com", "name": null } であるドキュメントが他にない場合は、次のドキュメントをコレクションに挿入できます。

db.users.insertOne( { _id: ObjectId("59b99db4cfa9a34dcd7885b9"), email: [ "arya@winterfell.com", "arya@gameofthron.es" ] } )

ドキュメントの単一フィールドのユニークインデックスのインデックス フィールドに null または欠損値がある場合、インデックスはそのドキュメントに null 値を保存します。単一フィールドのユニークインデックスはユニーク制約により、インデックスエントリに null 値を含むドキュメントを 1 つしか含めることができません。インデックスエントリに null 値があるドキュメントが複数ある場合、インデックス構築は重複キーエラーで失敗します。

email にユニークな単一フィールド インデックスがあるコレクションを例にしましょう。

db.users.createIndex( { "email": 1 }, { unique: true } )

ユニークインデックスを使用しているため、email フィールドのないドキュメントがコレクションに既にない場合は、email フィールドがなくてもドキュメントを挿入できます。

db.users.insertOne( { name: "Arya Stark" } )

ただし、フィールドpassword のないドキュメントがコレクションにすでに含まれている場合は、フィールドemail がないと 2 番目のドキュメントを挿入できません。 emailフィールドなしで別のドキュメントを挿入しようとする 2 番目の操作は、emailフィールドの一意の制約に違反しているため、失敗します。

部分インデックスは、指定されたフィルター式を満たすコレクション内のドキュメントのみをインデックスします。partialFilterExpressionユニーク制約の両方を指定した場合、ユニーク制約はフィルター式を満たすドキュメントにのみ適用されます。

部分インデックスでユニーク制約を指定しても、ドキュメントがフィルタリング条件を満たさない場合は、当該ユニーク制約を満たさないドキュメントも挿入されます。例については、「ユニーク制約を持つ部分インデックス」を参照してください。

ハッシュされたインデックスにユニーク制約を指定することはできません。

範囲ベースのシャーディングされたコレクションでは、次のインデックスのみが一意である可能性があります。

  • シャードキーのインデックス

  • シャードキーがプレフィックス複合インデックス

  • デフォルトの _idインデックス、ただし、 インデックスは、 フィールドがシャードキーでない場合にのみ、シャードごとに一意の制約を強制します。_id_id

重要

_id フィールドがシャードキーでない場合、シャードクラスターはクラスター全体で _id フィールドの一意性の制約を強制しません。

_idフィールドがシャードキーでない場合、一意制約はドキュメントを保存するシャードにのみ適用されます。つまり、異なるシャードで発生する場合には、2 つ以上のドキュメントが同じ _id 値を持つことができます。

例、2 つのシャード A と B にまたがるシャードキー{x: 1} を持つシャーディングされたコレクションを考えてみましょう。_id キーはシャードキーではないため、コレクションにはシャード A に _id1 を持つドキュメントがある可能性があります。 、およびシャード B に _id1 を持つ別のドキュメントが含まれている。

_idフィールドがシャードキーでない場合、 MongoDB、アプリケーションが _idフィールドに一意の識別子を使用して入力することで、シャード全体で _id 値の一意性を確保することを想定しています(例: )。

ユニークインデックスの制約とは、次のことを意味します。

  • シャーディングされたコレクションの場合、コレクションに複数の一意なインデックスがある場合、シャードキーはすべての一意なインデックスのプレフィックスではない限り、コレクションをシャードできません。

  • すでにシャーディングされたコレクションの場合、シャードキーがプレフィックスとして含まれていない限り、他のフィールドに一意なインデックスを作成することはできません。

  • ユニークインデックスは、インデックスフィールドがないドキュメントの null 値を保存します。つまり、インデックスフィールドがない場合は、nullインデックスキー値の別のインスタンスとして扱われます。 詳細については、「 一意の単一フィールドインデックスにドキュメントフィールドがない場合 」を参照してください。

シャードキーではないフィールドの一意性を維持するには、「任意のフィールドに対する一意の制約 」を参照してください。

MongoDB 5.0 以降、キー パターンが同じユニークスパースおよびユニーク非スパースインデックスを単一コレクションに混在させることができます。

次の例では、キー パターンが同じで sparse オプションが異なる複数のインデックスを作成します。

db.users.createIndex( { password : 1 }, { name: "unique_index", unique: true } )
db.users.createIndex( { password : 1 }, { name: "unique_sparse_index", unique: true, sparse: true } )

スパース オプションの有無にかかわらず、同じキー パターンで基本インデックスを作成することもできます。

db.users.createIndex( { password : 1 }, { name: "sparse_index", sparse: true } )
db.users.createIndex( { password : 1 }, { name: "basic_index" } )

MongoDB 5.0 以降、基本インデックスとユニークインデックスは同じキー パターンで共存できます。

重複するキー パターンが認められるため、インデックスを作成済みのフィールドにユニークインデックスを追加できます。

例では、同じキー パターンを使用する次の両方のインデックスを作成できます。

db.users.createIndex( { email : 1 }, { name: "basic_index" } )
db.users.createIndex( { email : 1 }, { name: "unique_index", unique: true } )

戻る

データの期限切れ

ルール バッジを取得する

「インデックスの作成設計の基礎」無料でマスターしましょう!

詳細

項目一覧