แตกต่างกัน

คำอธิบาย

ค้นหาชุดค่าผสมที่ไม่ซ้ำกันทั้งหมดของค่าสำหรับชุดนิพจน์

ระยะ distinct(...) มีไวยากรณ์คล้ายกับ select(...) เนื่องจากใช้ได้กับนิพจน์ที่เลือกได้ตั้งแต่ 1 รายการขึ้นไป โดยสามารถใช้สตริงได้เมื่อนิพจน์เป็นเพียงการอ้างอิงฟิลด์

ตัวอย่าง

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

พฤติกรรม

ระยะ 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 จะให้ข้อมูลเกี่ยวกับแผนการดำเนินการค้นหาจริงและข้อมูลการสร้างโปรไฟล์เพื่อช่วยในการแก้ไขข้อบกพร่อง