Отчетливый

Описание

Найдите все различные комбинации значений для ряда выражений.

Этап distinct(...) имеет синтаксис, аналогичный 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();

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")));
Быстрый
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(...) работает аналогично этапу 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();

получить:

{ country: "USA", normalized_state: "ca" }
{ country: "USA", normalized_state: "ny" }
{ country: "Canada", normalized_state: null }
{ country: "Mexico", normalized_state: null }

Поведение эквивалентности

Поведение, связанное с эквивалентностью различных значений, подчиняется той же семантике, что и равенства.

Это означает, что эквивалентные значения, например, математически эквивалентные числовые значения, независимо от исходных типов (32-битное целое число, 64-битное целое число, числа с плавающей запятой, десятичные числа и т. д.), считаются одним и тем же уникальным значением.

Например, в коллекции numerics , содержащей различные документы со значениями foo , представляющими собой 32-битное целое число 1 , 64-битное целое число 1L и число с плавающей запятой 1.0 соответственно, distinct(...) вернет только 1 результат.

В случаях, когда в наборе данных присутствуют различные эквивалентные значения, выходное значение группы может быть любым из этих эквивалентных значений. В этом примере значение foo может быть возвращено как 1 , 1L или 1.0 .

Даже если кажется, что всё происходит детерминированно, не следует полагаться на то, что будет выбрано какое-то конкретное значение.

Использование памяти

Способ выполнения этапа distinct(...) зависит от доступных индексов. Если оптимизатор запросов не выбрал подходящий индекс, distinct(...) требует буферизации всех уникальных значений в памяти.

В случае очень большого количества различных значений или очень больших значений (например, различных значений), на этом этапе может закончиться память.

В таких случаях следует применять фильтры для ограничения набора данных, по которым будет выполняться операция distinct(...) , или создавать индексы, как рекомендуется, чтобы избежать большого потребления памяти.

Функция Query Explain предоставит информацию о фактическом плане выполнения запроса и данных профилирования, что поможет в отладке.