Riêng biệt

Mô tả

Tìm tất cả tổ hợp giá trị riêng biệt cho một loạt biểu thức.

Giai đoạn distinct(...) có cú pháp tương tự như select(...) vì giai đoạn này lấy một hoặc nhiều biểu thức có thể chọn. Bạn có thể sử dụng chuỗi khi biểu thức chỉ là một tham chiếu đến trường:

Ví dụ

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();
Bắt đầu
cities1, err := client.Pipeline().Collection("cities").Distinct(firestore.Fields("country")).Execute(ctx).Results().GetAll()
if err != nil {
	fmt.Fprintf(w, "GetAll failed: %v", err)
	return err
}

cities2, err := client.Pipeline().Collection("cities").
	Distinct(firestore.Fields(
		firestore.ToLower(firestore.FieldOf("state")).As("normalizedState"),
		firestore.FieldOf("country"),
	)).
	Execute(ctx).Results().GetAll()
if err != nil {
	fmt.Fprintf(w, "GetAll failed: %v", err)
	return err
}

Hành vi

Giai đoạn distinct(...) hoạt động tương tự như giai đoạn aggregate(...) mà không có nhóm. Xem thêm aggregate(...)select(...).

Tìm các giá trị trường riêng biệt

Ví dụ: để lấy danh sách mọi quốc gia trong tập hợp cities sau đây:

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"});

Bạn có thể tìm thấy các quốc gia riêng biệt bằng cách sử dụng:

Node.js

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

tạo ra kết quả sau:

{ country: "USA" }
{ country: "Canada" }
{ country: "Mexico" }

Kết quả riêng biệt của biểu thức

Bạn cũng có thể tìm thấy các tổ hợp riêng biệt của nhiều trường hoặc các biểu thức phức tạp hơn. Ví dụ:

Node.js

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

để nhận:

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

Hành vi tương đương

Hành vi tương đương đối với các giá trị riêng biệt tuân theo cùng ngữ nghĩa như các đẳng thức.

Điều này có nghĩa là các giá trị tương đương, ví dụ: các giá trị số tương đương về mặt toán học, bất kể loại ban đầu (số nguyên 32 bit, số nguyên 64 bit, số dấu phẩy động, số thập phân, v.v.), đều được coi là cùng một giá trị riêng biệt.

Ví dụ: trong một tập hợp numerics có các tài liệu khác nhau chứa foo các giá trị của số nguyên 32 bit 1, số nguyên 64 bit 1L và số dấu phẩy động 1.0 tương ứng, distinct(...) sẽ chỉ trả về 1 kết quả.

Trong những trường hợp có các giá trị tương đương khác nhau trong tập dữ liệu, giá trị đầu ra của nhóm có thể là bất kỳ giá trị tương đương nào trong số này. Trong ví dụ này, giá trị foo này có thể được trả về dưới dạng 1, 1L hoặc 1.0.

Ngay cả khi có vẻ như là xác định, bạn cũng không nên cố gắng dựa vào hành vi của một giá trị cụ thể được chọn.

Mức sử dụng bộ nhớ

Cách thực thi giai đoạn distinct(...) phụ thuộc vào các chỉ mục hiện có. Khi không có chỉ mục thích hợp do trình tối ưu hoá truy vấn chọn, distinct(...) yêu cầu đệm tất cả các giá trị riêng biệt trong bộ nhớ.

Trong trường hợp có một số lượng rất lớn các giá trị riêng biệt hoặc các giá trị rất lớn (ví dụ: riêng biệt trên các giá trị lớn), giai đoạn này có thể hết bộ nhớ.

Trong những trường hợp như vậy, bạn nên áp dụng bộ lọc để giới hạn tập dữ liệu cần thực hiện distinct(...) hoặc tạo chỉ mục theo đề xuất để tránh sử dụng nhiều bộ nhớ.

Giải thích truy vấn sẽ cung cấp thông tin về kế hoạch thực thi truy vấn thực tế và dữ liệu lập hồ sơ để giúp gỡ lỗi.