Distinct

説明

前のステージのフィールドまたは式の個別の値を検索します。

構文

distinct ステージの構文は select と同様です。選択可能な 1 つ以上の式を受け取り、それらの式に基づいて個別の値を選択して検索します。式が単なるフィールド参照である場合は、文字列を使用できます。

Node.js

const cities = await db.pipeline()
  .collection('/cities')
  .distinct("country")
  .execute();

const cities = await db.pipeline()
  .collection('/cities')
  .distinct(
    field("state").toLower().as("normalized_state"),
    field("country"))
  .execute();

クライアントの例

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();

Web

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

var cities = db.pipeline()
    .collection("cities")
    .distinct("country")
    .execute()

cities = db.pipeline()
    .collection("cities")
    .distinct(
        field("state").toLower().alias("normalizedState"),
        field("country")
    )
    .execute()

Java

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 は重複除去を使用する select と似ています。そのため、select で使用できる選択可能な式は、distinct でも使用できます。

distinct ステージは、グループを使用しない集計ステージと同様に機能します。

集計ステージ選択ステージもご覧ください。

個別のフィールド値を検索する

たとえば、次の 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 進数など)に関係なく、同等の値(数学的に同等の数値など)は、同じ個別の値と見なされます。

たとえば、32 ビット整数 1、64 ビット整数 1L、浮動小数点数 1.0foo 値が格納されたさまざまなドキュメントを含むコレクション numerics では、distinct は 1 つの結果のみを返します。

データセットに異なる同等の値が存在する場合、グループの出力値はこれらの同等の値のいずれかになります。 この例では、foo のこの値は 11L、または 1.0 として返される可能性があります。

決定的に見える場合でも、特定の値が選択される動作に依存しようとすべきではありません

メモリ使用量

distinct ステージの実行方法は、使用可能なインデックスによって異なります。クエリ オプティマイザーによって適切なインデックスが選択されていない場合、distinct はメモリ内のすべての個別の値をバッファリングする必要があります。

個別の値の数が非常に多い場合や、値が非常に大きい場合(大きな値で一意など)、このステージでメモリ不足が発生する可能性があります。

このような場合は、フィルタを適用してデータセットを制限し、distinct を実行するか、推奨されるインデックスを作成して、メモリ使用量が増大しないようにする必要があります。

Query Explain では、実際のクエリ実行プランとプロファイリング データに関する情報が提供され、デバッグに役立ちます。