複合ワイルドカード インデックス
項目一覧
バージョン 7.0 で追加。
MongoDB は、フィールドまたはフィールドのセットに対するワイルドカード インデックスの作成をサポートしています。 複合インデックスには複数のインデックスタームがあります。 複合ワイルドカード インデックスには、1 つのワイルドカードタームと 1 つ以上の追加のインデックスタームがあります。
重要
ワイルドカード インデックスはワークロードベースのインデックス プランニングを置き換えるものではありません。
ワークロードをサポートするインデックスの作成の詳細については、「クエリをサポートするインデックスの作成を参照してください。
ユースケース
属性パターンを使用した検索
属性パターンは、共通の特徴を持つドキュメントを検索するのに便利な手法です。
残念ながら、可能なすべてのクエリをカバーするために個別のインデックスを多数作成するとコストがかかります。 ワイルドカード インデックスは、1 つのワイルドカード インデックスで多数の潜在的なクエリを効率的にカバーできるため、多数の個別のインデックスを作成するよりも適しています。
次のようなスキーマについて考えてみましょう。
{ tenantId: <Number>, tenantRegion: <Number>, customFields: { addr: <String>, name: <String>, blockId: <Number>, ... } dateOpened: <Date> }
特定のtenantId
を持つテナントについて、 customFields
フィールドの一部をクエリすることをお勧めします。 一連の個別インデックスを作成できます。
{ tenantId: 1, "customFields.addr": 1 } { tenantId: 1, "customFields.name": 1 } { tenantId: 1, "customFields.blockId": 1 } ...
このアプローチは維持が困難であり、コレクションあたりのインデックスの最大数(64)に達する可能性が高くなります。
代わりに複合ワイルドカード インデックスを使用してください。 複合ワイルドカード インデックスは書き込みが簡単で、維持が簡単で、インデックス コレクションの制限である 64 に達する可能性は低くなります。
次の例では、 salesData
コレクションに複合ワイルドカード インデックスを作成しています。
db.runCommand( { createIndexes: "salesData", indexes: [ { key: { tenantId: 1, "customFields.$**": 1 }, name: "tenant_customFields" } ] } )
ワイルドカード"customFields.$**"
は、 customFields
フィールドのすべてのサブフィールドを指定します。 その他のインデックスタームtenantId
は、ワイルドカード指定ではありません。これは、標準のフィールド仕様です。
動作
ワイルドカード インデックスを作成するには、次の標準のインデックス作成コマンドを使用します。
ワイルドカード インデックスに関する一般的な考慮事項
ワイルドカード インデックスでは、デフォルトで
_id
フィールドが省略されます。 ワイルドカード インデックスに_id
フィールドを含めるには、wildcardProjection
ドキュメントに明示的に含める必要があります。db.salesData.createIndex( { "$**" : 1 }, { "wildcardProjection" : { "_id": 1, "customers.lastName": 1, "customers.FirstName": 1, } } ) コレクションに複数のワイルドカード インデックスを作成できます。
ワイルドカード インデックスは、コレクション内の他のインデックスと同じフィールドをカバーする場合があります。
ワイルドカード インデックスはスパースです。 インデックス フィールドを含むドキュメントのエントリのみが含まれます。
複合ワイルドカード インデックスのすべてのフィールドがない場合、ドキュメントにインデックスは作成されません。
複合ワイルドカード インデックスに関する考慮事項
複合ワイルドカード インデックスは スパース インデックスです。
ドキュメントは、 ワイルドカード フィールドがなくても 複合フィールドの 1 つがある場合はインデックスに含まれます。
ワイルドカード フィールドを含むインデックス フィールドは、昇順(
1
)または降順(-1
)でソートできます。
はじめる
でフィールドをフィルタリングする wildcardProjection
個々のサブフィールドを指定するには、 wildcardProjection
を使用します。
db.runCommand( { createIndexes: "salesData", indexes: [ { key: { tenantId: 1, "$**": 1 }, name: "tenant_customFields_projection", wildcardProjection: { "customFields.addr": 1, "customFields.name": 1 } } ] } )
ワイルドカード インデックス ターム"$**"
は、コレクション内のすべてのフィールドを指定します。 wildcardProjection
は、指定されたフィールド"customFields.addr"
と"customFields.name"
にインデックスを制限します。
ワイルドカード タームが$**
の場合にのみwildcardProjection
を使用できます。
ヘルパー メソッドを使用したワイルドカード インデックスの作成
は、ほとんどのMongoDB データベースコマンド でshell ヘルパー メソッド を提供します。これらの shell メソッドは簡素化された構文を提供し、機能的にはデータベースコマンドと同等です。
shell最初の例 の ヘルパーは次のとおりです。
db.salesData.createIndex( { tenantId: 1, "customFields.$**": 1 }, { name: "tenant_customFields_shellHelper" } )
shell2 つ目の例 の ヘルパーは次のとおりです。
db.salesData.createIndex( { tenantId: 1, "$**": 1 }, { "wildcardProjection": { "customFields.addr": 1, "customFields.name": 1 }, name: "tenant_customFields_projection_helper" } )
shell コマンドとデータベースコマンドを比較する場合は、コマンド呼び出しの間にインデックスを削除する必要があります。 名前が異なる場合でも、同じインデックスを 2 回作成することはできません。
インデックスを削除するには、インデックス名を挿入してdb.collection.dropIndex() を実行します。
db.salesData.dropIndex( "tenant_customFields" )
上記のコマンドは、 salesData
データベースから"tenant_customFields"
インデックスを削除します。
部分的な複合ワイルドカード インデックスの作成
部分的な 複合ワイルドカードを作成するには、 オプションを使用してフィルター式を指定し、フィルター条件に一致するドキュメントのみがインデックスに含まれるようにします。partialFilterExpression
partialFilterExpression
は、インデックスに含まれるフィールドと含まれないフィールドをカバーできます。
次の例では、 tenantId
フィールドと customFields
フィールドのすべてのサブフィールド に部分的な複合ワイルドカードを作成し、tenantRegion
が 1
であるドキュメントのみに作成します。
db.runCommand( { createIndexes: "salesData", indexes: [ { key: { tenantId: 1, "customFields.$**": 1 }, name: "tenant_customFields_partial", partialFilterExpression: { tenantRegion: 1 } } ] } )