定義
distinct単一のコレクション全体で指定されたフィールドの個別の値を検索します。
distinctは、個別の値の配列を含むドキュメントを返します。返されるドキュメントには、クエリ統計とクエリプランが付属する埋め込みドキュメントも含まれます。Tip
mongoshでは、このコマンドはdb.collection.distinct()ヘルパー メソッドを通じて実行することもできます。ヘルパー メソッドは
mongoshユーザーには便利ですが、データベースコマンドと同じレベルの情報は返されない可能性があります。 便宜上必要ない場合、または追加の戻りフィールドが必要な場合は、 データベースコマンドを使用します。
互換性
このコマンドは、次の環境でホストされている配置で使用できます。
MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
重要
このコマンドは、M0 およびフレックス クラスターで限定的にサポートされています。詳細については、「サポートされていないコマンド」を参照してください。
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
構文
このコマンドの構文は、次のとおりです。
db.runCommand( { distinct: "<collection>", key: "<field>", query: <query>, readConcern: <read concern document>, collation: <collation document>, comment: <any> } )
コマンドフィールド
このコマンドは、次のフィールドを使用します。
フィールド | タイプ | 説明 | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| string | 個別の値をクエリするコレクションの名前。 | ||||||||||
| string | 個別の値を返すフィールド。 | ||||||||||
| ドキュメント | 任意。個別の値を取得するドキュメントを指定するクエリ。 | ||||||||||
| ドキュメント | 任意。読み取り保証 (read concern) を指定します。
次の読み取り保証レベルが利用できます。
読み取り保証 (read concern) のレベルについて詳しくは、「読み取り保証 (read concern) レベル」を参照してください。 | ||||||||||
| ドキュメント | 任意。 操作に使用する照合を指定します。 照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。 照合オプションの構文は次のとおりです。 照合を指定する場合、 照合が指定されていなくても、コレクションにデフォルトの照合が設定されている場合( コレクションにも操作にも照合が指定されていない場合、MongoDB では以前のバージョンで使用されていた単純なバイナリ比較によって文字列が比較されます。 1 つの操作に複数の照合は指定できません。たとえば、フィールドごとに異なる照合を指定できません。また、ソートと検索を一度に実行する場合、検索とソートで別の照合を使用できません。 | ||||||||||
| any | 任意。このコマンドに添付するユーザー指定のコメント。設定すると、このコメントは以下の場所にこのコマンドの記録と合わせて表示されます。
コメントには、有効な BSON 型(string, integer, object, array など)を使用できます。 |
注意
結果は BSON サイズの最大を超えることはできません。結果が BSON サイズの最大を超える場合は、「集計パイプラインを使用した個別の値の取得」で説明されているように、$group 演算子を使用して集計パイプラインで個別の値を取得します。
MongoDB は、 コマンド用の shell ラッパー メソッドdb.collection.distinct() distinctも提供します。さらに、多くの MongoDBドライバーは ラッパー メソッドを提供します。 具体的なドライバーのドキュメントを参照してください。
動作
シャーディングされたクラスターでは、distinct コマンドが 孤立したドキュメントを返す場合があります。
時系列コレクションの場合、distinct コマンドはインデックスを効率的に使用できません。代わりに、$group 集計を使用して、ドキュメントを個別の値でグループ化します。詳細は「時系列の制限」をご覧ください。
配列フィールド
指定された field の値が配列の場合、 distinct では配列の各要素が別個の値として扱われます。
たとえば、フィールドの値が [ 1, [1], 1 ] の場合、distinct は 1、[1]、1 を別々の値として扱います。
MongoDB 6.0 以降では、配列を使用する場合、 distinct コマンドではコレクションとビューに対して同じ結果が返されます。
例については、以下を参照してください。
インデックスの使用
可能な場合、 distinct 操作ではインデックスを使用できます。
インデックスは distinct操作もカバーできます。インデックスによってカバーされるクエリの詳細については、「カバーされたクエリの実行」を参照してください。
トランザクション
トランザクション内で個別の操作を実行するには、以下を使用できます。
シャーディングされていないコレクションの場合、
db.collection.distinct()メソッドやdistinctコマンドと、$groupステージの集計パイプラインを使用できます。シャーディングされたコレクションの場合、
db.collection.distinct()メソッド、またはdistinctコマンドは使用できません。シャーディングされたコレクションの個別の値を検索するには、代わりに
$groupステージで集計パイプラインを使用します。詳細については、「個別の操作」を参照してください。
重要
ほとんどの場合、分散トランザクションでは 1 つのドキュメントの書き込み (write) よりもパフォーマンス コストが高くなります。分散トランザクションの可用性は、効果的なスキーマ設計の代わりにはなりません。多くのシナリオにおいて、非正規化されたデータモデル(埋め込みドキュメントと配列)が引き続きデータやユースケースに最適です。つまり、多くのシナリオにおいて、データを適切にモデリングすることで、分散トランザクションの必要性を最小限に抑えることができます。
トランザクションの使用に関するその他の考慮事項(ランタイム制限や oplog サイズ制限など)については、「本番環境での考慮事項」も参照してください。
クライアントの切断
操作が完了する前にdistinctを発行したクライアントが切断された場合、MongoDB はdistinctをkillOpを使用して終了対象としてマークします。
レプリカセット ノードの状態の制限
レプリカセット ノード上で distinct 操作を実行するには、ノードが PRIMARY または SECONDARY状態である必要があります。ノードが STARTUP2 などの別の状態にある場合、操作はエラーになります。
インデックスフィルターと照合
MongoDB 6.0 以降、インデックス フィルターは、以前はplanCacheSetFilter コマンドを使用して設定されていた照合を使用します。
例
この例では、次のドキュメントを含む inventory コレクションを使用します。
{ "_id": 1, "dept": "A", "item": { "sku": "111", "color": "red" }, "sizes": [ "S", "M" ] } { "_id": 2, "dept": "A", "item": { "sku": "111", "color": "blue" }, "sizes": [ "M", "L" ] } { "_id": 3, "dept": "B", "item": { "sku": "222", "color": "blue" }, "sizes": "S" } { "_id": 4, "dept": "A", "item": { "sku": "333", "color": "black" }, "sizes": [ "S" ] }
フィールドの個別の値を返す
次の例では、inventory コレクション内のすべてのドキュメントからフィールド dept の個別の値を返します。
db.runCommand ( { distinct: "inventory", key: "dept" } )
このコマンドは、個別の dept 値を含む values という名前のフィールドがあるドキュメントを返します。
{ "values" : [ "A", "B" ], "ok" : 1 }
埋め込みフィールドの個別の値を返す
次の例では、inventory コレクション内のすべてのドキュメントから、item フィールドに埋め込まれたフィールド sku の個別の値を返します。
db.runCommand ( { distinct: "inventory", key: "item.sku" } )
このコマンドは、個別の sku 値を含む values という名前のフィールドがあるドキュメントを返します。
{ "values" : [ "111", "222", "333" ], "ok" : 1 }
Tip
埋め込みドキュメント内のフィールドへのアクセスに関する情報は、ドット表記 を参照してください。
配列フィールドの個別の値を返す
次の例では、inventory コレクション内のすべてのドキュメントからフィールド sizes の個別の値を返します。
db.runCommand ( { distinct: "inventory", key: "sizes" } )
このコマンドは、個別の sizes 値を含む values という名前のフィールドがあるドキュメントを返します。
{ "values" : [ "M", "S", "L" ], "ok" : 1 }
コレクションとビュー内の配列
MongoDB 6.0 以降では、配列を使用する場合、 distinct コマンドではコレクションとビューに対して同じ結果が返されます。
次の例では、各ドキュメントの温度値の配列を含む sensor という名前のコレクションを作成します。
db.sensor.insertMany( [ { _id: 0, temperatures: [ { value: 1 }, { value: 4 } ] }, { _id: 1, temperatures: [ { value: 2 }, { value: 8 } ] }, { _id: 2, temperatures: [ { value: 3 }, { value: 12 } ] }, { _id: 3, temperatures: [ { value: 1 }, { value: 4 } ] } ] )
次の例では sensor コレクションから sensorView という名前のビューを作成します。
db.createView( "sensorView", "sensor", [] )
次の例では distinct を使用して sensor コレクション内の temperatures 配列から一意の値を取得します。
db.sensor.distinct( "temperatures.1.value" )
temperatures.1.value 内の 1 は、temperatures の配列インデックスを指定します。
出力例:
[ 4, 8, 12 ]
sensorView の例:
db.sensorView.distinct( "temperatures.1.value" )
出力例:
[ 4, 8, 12 ]MongoDB 6.0 以降(sensorコレクションから返される結果と同一)。[]MongoDB 6.0 以前のバージョン
クエリの指定 distinct
次の例では、item フィールドに埋め込まれたフィールド sku の個別の値を、dept が "A" に等しいドキュメントから返します。
db.runCommand ( { distinct: "inventory", key: "item.sku", query: { dept: "A"} } )
このコマンドは、個別の sku 値を含む values という名前のフィールドがあるドキュメントを返します。
{ "values" : [ "111", "333" ], "ok" : 1 }
照合の指定
照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。
コレクション myCollは、次のドキュメントを含みます。
{ _id: 1, category: "café", status: "A" } { _id: 2, category: "cafe", status: "a" } { _id: 3, category: "cafE", status: "a" }
下記の集計操作には 照合オプションが含まれます。
db.runCommand( { distinct: "myColl", key: "category", collation: { locale: "fr", strength: 1 } } )
照合フィールドの説明については、照合ドキュメントを参照してください。
デフォルトの読み取り保証を上書き
デフォルトの読み取り保証 (read concern) レベル "local" を無効にするには、readConcern オプションを使用します。
レプリカセットに対する次の操作では、大多数のノードに書き込まれたことが確認されたデータの最新のコピーを読み取るために、"majority" の 読み取り保証を指定します。
注意
読み取り保証のレベルを問わず、ノード上の最新データにシステム内のデータの最新バージョンが反映されていない場合があります。
db.runCommand( { distinct: "restaurants", key: "rating", query: { cuisine: "italian" }, readConcern: { level: "majority" } } )
単一のスレッドでそれ自体の書き込みの読み取りを可能にするには、レプリカセットのプライマリに対して "majority" 読み取り保証と "majority" 書込み保証を使用します。