Distinct(変換ステージ)
説明
一連の式の値の個別の組み合わせをすべて検索します。
distinct(...) ステージは、1 つ以上の選択可能な式を受け取るため、select(...) と同様の構文を持ちます。式が単なるフィールド参照である場合は、文字列を使用できます。
例
Node.js
let cities = await db.pipeline() .collection("cities") .distinct("country") .execute(); cities = await db.pipeline() .collection("cities") .distinct( field("state").toLower().as("normalizedState"), field("country")) .execute();
ウェブ
let cities = await execute(db.pipeline() .collection("cities") .distinct("country")); cities = await execute(db.pipeline() .collection("cities") .distinct( field("state").toLower().as("normalizedState"), field("country")));
Swift
let results = try await db.pipeline() .collection("books") .distinct([ Field("author").toUpper().as("author"), Field("genre") ]) .execute()
Kotlin
Android
var cities = db.pipeline() .collection("cities") .distinct("country") .execute() cities = db.pipeline() .collection("cities") .distinct( field("state").toLower().alias("normalizedState"), field("country") ) .execute()
Java
Android
Task<Pipeline.Snapshot> cities; cities = db.pipeline() .collection("cities") .distinct("country") .execute(); cities = db.pipeline() .collection("cities") .distinct( field("state").toLower().alias("normalizedState"), field("country")) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field cities = client.pipeline().collection("cities").distinct("country").execute() cities = ( client.pipeline() .collection("cities") .distinct(Field.of("state").to_lower().as_("normalizedState"), "country") .execute() )
Java
Pipeline.Snapshot cities1 = firestore.pipeline().collection("cities").distinct("country").execute().get(); Pipeline.Snapshot cities2 = firestore .pipeline() .collection("cities") .distinct(toLower(field("state")).as("normalizedState"), field("country")) .execute() .get();
行動
distinct(...) ステージは、グループを使用しない
aggregate(...) ステージと同様に機能します。
aggregate(...) と
select(...) もご覧ください。
個別のフィールド値を検索する
たとえば、次の cities コレクション内のすべての国のリストを取得するには、次のようにします。
Node.js
await db.collection("cities").doc("SF").set({name: "San Francisco", state: "CA", country: "USA"});
await db.collection("cities").doc("LA").set({name: "Los Angeles", state: "CA", country: "USA"});
await db.collection("cities").doc("NY").set({name: "New York", state: "NY", country: "USA"});
await db.collection("cities").doc("TOR").set({name: "Toronto", state: null, country: "Canada"});
await db.collection("cities").doc("MEX").set({name: "Mexico City", state: null, country: "Mexico"});
個別の国は、次の方法で確認できます。
Node.js
const cities = await db.pipeline()
.collection("/cities")
.distinct("country")
.execute();
結果は次のようになります。
{ country: "USA" }
{ country: "Canada" }
{ country: "Mexico" }
式の個別の出力
複数のフィールドの個別の組み合わせや、より複雑な式を見つけることもできます。次に例を示します。
Node.js
const cities = await db.pipeline()
.collection("/cities")
.distinct(
field("state").toLower().as("normalized_state"),
field("country"))
.execute();
to get:
{ country: "USA", normalized_state: "ca" }
{ country: "USA", normalized_state: "ny" }
{ country: "Canada", normalized_state: null }
{ country: "Mexico", normalized_state: null }
同値動作
個別の値に対する同値動作は、等値性と同じセマンティクスに従います。
つまり、元の型(32 ビット整数、64 ビット整数、浮動小数点数、10 進数など)に関係なく、同等の値(数学的に同等の数値など)は、同じ個別の値と見なされます。
たとえば、さまざまなドキュメントを含むコレクション numerics では、32 ビット整数 1、64 ビット整数 1L、浮動小数点数 1.0 の値を含む
foo は、distinct(...) が 1 つの結果のみを返します。
データセットに異なる同等の値が存在する場合、グループの出力値はこれらの同等の値のいずれか になります。
この例では、foo のこの値は 1、1L、または 1.0 として返される可能性があります。
決定的に見える場合でも、特定の値が選択される動作に依存しようとすべきではありません。
メモリ使用量
distinct(...) ステージの実行方法は、使用可能なインデックスによって異なります。クエリ オプティマイザーによって適切なインデックスが選択されていない場合、distinct(...) はメモリ内のすべての個別の値をバッファリングする必要があります。
個別の値の数が非常に多い場合や、値が非常に大きい場合(大きな値で一意など)、このステージでメモリ不足が発生する可能性があります。
このような場合は、フィルタを適用してデータセットを制限し、distinct(...) を実行するか、推奨されるインデックスを作成して、メモリ使用量が増大しないようにする必要があります。
Query Explain では、実際のクエリ実行プランとプロファイリング データに関する情報が提供され、デバッグに役立ちます。