ハッシュされたインデックス
ハッシュされたインデックスは、インデックス フィールドの値のハッシュを持つエントリを保持します。
ハッシュされたインデックスは、ハッシュされたシャードキーを使用したシャーディングをサポートします。 ハッシュベースのシャーディングでは、フィールドのハッシュされたインデックスをシャードキーとして使用し、シャーディングされたクラスター全体でデータをパーティション分割します。
ハッシュされたシャードキー を使用してコレクションをシャーディングすると、データがより均等に分散されます。 詳細については、「ハッシュされたシャーディング 」を参照してください。
ハッシュ関数
ハッシュされたインデックスは、ハッシュ関数を使用してインデックス フィールドの値のハッシュを計算します。 [1]ハッシュ関数は埋め込みドキュメントをまとめて、値全体のハッシュを計算しますが、マルチキー( 配列)インデックス。 具体的には、配列を含むフィールドでハッシュされたインデックスを作成したり、またはハッシュされたインデックス フィールドに配列を挿入しようとすると、エラーが返されます。
Tip
MongoDB は、ハッシュされたインデックスを使用してクエリを解決するときに、ハッシュを自動計算するため、アプリケーションでハッシュを計算する必要がありません。
[1] | バージョン4.0以降、 mongosh は メソッドconvertShardKeyToHashed() を提供します。 このメソッドは、ハッシュイされたンデックスと同じハッシュ関数を使用するため、キーのハッシュ値がどうなるかを確認できます。 |
ハッシュ インデックスの作成
ハッシュ インデックスを作成するには、次の例のように、インデックス キーの値としてhashed
を指定します。
db.collection.createIndex( { _id: "hashed" } )
ハッシュされた複合インデックスの作成
バージョン 4.4 で追加。
MongoDB 4.4 以降、MongoDB は、単一の ハッシュされた フィールドを含む複合インデックスの作成をサポートしています。 ハッシュされた複合インデックスを作成するには、インデックスを作成するときに任意の単一のインデックスキーの値としてhashed
を指定します。
db.collection.createIndex( { "fieldA" : 1, "fieldB" : "hashed", "fieldC" : -1 } )
ハッシュされた複合インデックスでは、 featureCompatibilityVersionを4.4
に設定する必要があります。
Considerations
埋め込みドキュメント
ハッシュ関数は、埋め込みドキュメントをまとめて値全体のハッシュを計算しますが、マルチキー( 配列)インデックス。 具体的には、配列を含むフィールドでハッシュされたインデックスを作成したり、またはハッシュされたインデックス フィールドに配列を挿入しようとするとエラーが返されます。
ユニーク制約
MongoDB では、 hashed
インデックスで一意の制約を指定することはサポートされていません。 代わりに、そのフィールドに一意の制約を持つハッシュされていないインデックスを追加で作成できます。 MongoDB は ハッシュされていないインデックスを使用して フィールドの一意性を強制できます。
2 53 Limit
警告
MongoDB hashed
インデックスは、ハッシュする前に浮動小数点数を 64 ビット整数に切り捨てます。たとえば、hashed
インデックスは 2.3
、2.2
、2.9
の値を持つフィールドに同じ値をストアします。衝突を防ぐため、64 ビット整数に確実に変換できない(そして浮動小数点に戻せない)浮動小数点数には hashed
インデックスを使用しないでください。MongoDB hashed
インデックスは 2 53より大きい浮動小数点値をサポートしていません。
キーのハッシュされた値を確認するには、convertShardKeyToHashed()
を参照してください。
PowerPC と263
ハッシュされたインデックスの場合、MongoDB 4.2 では、PowerPC 上の浮動小数点値 2 63のハッシュ値が他のプラットフォームと整合性があることが保証されます。
2 53 より大きい浮動小数点値を含む可能性のあるフィールドの ハッシュされたインデックス はサポートされていない構成ですが、クライアントはインデックス フィールドの値が 2 63 であるドキュメントを挿入できます。
配置内のすべてのコレクションのすべてのhashed
インデックスを一覧表示するには、 mongosh
で次の操作を使用します。
db.adminCommand("listDatabases").databases.forEach(function(d){ let mdb = db.getSiblingDB(d.name); mdb.getCollectionInfos({ type: "collection" }).forEach(function(c){ let currentCollection = mdb.getCollection(c.name); currentCollection.getIndexes().forEach(function(idx){ let idxValues = Object.values(Object.assign({}, idx.key)); if (idxValues.includes("hashed")) { print("Hashed index: " + idx.name + " on " + d.name + "." + c.name); printjson(idx); }; }); }); });
インデックス付きフィールドに値 2 63が含まれているかどうかを確認するには、 コレクションとインデックス付きフィールドに対して次の操作を実行します。
インデックス フィールド タイプがスカラーで、ドキュメントでない場合:
// substitute the actual collection name for <collection> // substitute the actual indexed field name for <indexfield> db.<collection>.find( { <indexfield>: Math.pow(2,63) } ); インデックス付きフィールドタイプがドキュメント(またはスカラー)の場合は、次を実行できます。
// substitute the actual collection name for <collection> // substitute the actual indexed field name for <indexfield> db.<collection>.find({ $where: function() { function findVal(obj, val) { if (obj === val) return true; for (const child in obj) { if (findVal(obj[child], val)) { return true; } } return false; } return findVal(this.<indexfield>, Math.pow(2, 63)); } })