การค้นหาด้วยตัวกรองช่วงและความไม่เท่ากันในภาพรวมช่องหลายช่อง

Cloud Firestore รองรับการใช้ตัวกรองช่วงและความไม่เท่าเทียมในหลายช่องในการค้นหาเดียว คุณสามารถกำหนดเงื่อนไขของช่วงและอสมการในหลายๆ ฟิลด์ให้ง่ายขึ้นได้ การพัฒนาแอปพลิเคชันโดยมอบสิทธิ์การใช้ตรรกะหลังการกรองให้กับ Cloud Firestore

ตัวกรองช่วงและอสมการในหลายฟิลด์

ข้อความค้นหาต่อไปนี้ใช้ตัวกรองช่วงในประชากรและความหนาแน่นเพื่อแสดงผลทั้งหมด เมืองที่มีประชากรมากกว่า 1,000,000 คนและความหนาแน่นของประชากร คือน้อยกว่า 10,000 คนต่อหน่วยพื้นที่

เวอร์ชันเว็บ 9 แบบแยกส่วน

const q = query(
    collection(db, "cities"),
    where('population', '>', 1000000),
    where('density', '<', 10000),
  );

Swift

let query = db.collection("cities")
  .whereField("population", isGreaterThan: 1000000)
  .whereField("density", isLessThan: 10000)

Objective-C

FIRQuery *query =
 [[[[self.db collectionWithPath:@"cities"]
queryWhereField:@"population" isGreaterThan:@1000000]
   queryWhereField:@"density" isLessThan:@10000];

Java Android

Query query = db.collection("cities")
 .whereGreaterThan("population", 1000000)
 .whereLessThan("density", 10000);

Kotlin+KTX Android

val query = db.collection("cities")
 .whereGreaterThan("population", 1000000)
 .whereLessThan("density", 10000)

Go

   query := client.Collection("cities").
      Where("population", ">", 1000000).
      Where("density", "<", 10000)

Java

db.collection("cities")
  .whereGreaterThan("population", 1000000)
  .whereLessThan("density", 10000);

Node.js

db.collection("cities")
  .where('population', '>', 1000000),
  .where('density', '<', 10000)

Python

from google.cloud import firestore

db = firestore.Client()
query = db.collection("cities")
.where("population", ">", 1000000)
.where("density", "<", 10000)

PHP

$collection = $db->collection('samples/php/cities');
$chainedQuery = $collection
    ->where('population', '>', 1000000)
    ->where('density', '<', 10000);

C#

CollectionReference citiesRef = db.Collection("cities");
Query query = citiesRef
    .WhereGreaterThan("Population", 1000000)
    .WhereLessThan("Density", 10000);
QuerySnapshot querySnapshot = await query.GetSnapshotAsync();
foreach (DocumentSnapshot documentSnapshot in querySnapshot)
{
    var name = documentSnapshot.GetValue<string>("Name");
    var population = documentSnapshot.GetValue<int>("Population");
    var density = documentSnapshot.GetValue<int>("Density");
    Console.WriteLine($"City '{name}' returned by query. Population={population}; Density={density}");
}

Ruby

query = cities_ref.where("population", ">", "1000000")
                  .where("density", "<", 10000)

C++

CollectionReference cities_ref = db->Collection("cities");
Query query = cities_ref.WhereGreaterThan("population", FieldValue::Integer(1000000))
                       .WhereLessThan("density", FieldValue::Integer(10000));

Unity

CollectionReference citiesRef = db.Collection("cities");
Query query = citiesRef.WhereGreaterThan("population", 1000000)
                      .WhereLessThan("density", 10000);

Dart

final citiesRef = FirebaseFirestore.instance.collection('cities')
final query = citiesRef.where("population", isGreaterThan: 1000000)
                  .where("density", isLessThan: 10000);

ข้อควรพิจารณาเกี่ยวกับการจัดทำดัชนี

ก่อนที่จะเรียกใช้คำค้นหา โปรดอ่าน เกี่ยวกับการค้นหาและโมเดลข้อมูล Cloud Firestore

ใน Cloud Firestore เงื่อนไข ORDER BY ของการค้นหาจะเป็นตัวกำหนดดัชนี สามารถใช้เพื่อแสดงข้อความค้นหา เช่น คำค้นหา ORDER BY a ASC, b ASC ต้องมีดัชนีผสมในฟิลด์ a ASC, b ASC

หากต้องการเพิ่มประสิทธิภาพและต้นทุนของการค้นหา Cloud Firestore เพิ่มประสิทธิภาพลำดับของช่องในดัชนี ในการดำเนินการนี้ ตรวจสอบให้แน่ใจว่าดัชนีของคุณ เรียงลำดับจากซ้ายไปขวาจนข้อความค้นหากลั่นไปยังชุดข้อมูลที่ ช่วยป้องกันการสแกนรายการดัชนีที่ไม่จำเป็น

สมมติว่าคุณต้องการค้นหาชุดพนักงาน และค้นหาสหรัฐอเมริกา พนักงานที่มีเงินเดือนมากกว่า $100,000 และจำนวนปีของประสบการณ์ มากกว่า 0 จากความเข้าใจที่คุณมีต่อชุดข้อมูลนี้ คุณทราบว่า ข้อจำกัดด้านเงินเดือนจะเลือกมากกว่าข้อจำกัดด้านประสบการณ์ อุดมคติ ที่จะลดจำนวนการสแกนดัชนีลง (salary [...], experience [...]) ดังนั้น การค้นหาที่เร็วและ ความคุ้มค่าจะสั่งซื้อ salary ก่อนวันที่ experience และมีลักษณะดังนี้

Java

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .whereGreaterThan("experience", 0)
  .orderBy("salary")
  .orderBy("experience");

Node.js

db.collection("employees")
  .where("salary", ">", 100000)
  .where("experience", ">", 0)
  .orderBy("salary")
  .orderBy("experience");

Python

db.collection("employees")
  .where("salary", ">", 100000)
  .where("experience", ">", 0)
  .order_by("salary")
  .order_by("experience");

แนวทางปฏิบัติแนะนำในการเพิ่มประสิทธิภาพดัชนี

โปรดคํานึงถึงแนวทางปฏิบัติแนะนําต่อไปนี้เมื่อเพิ่มประสิทธิภาพดัชนี

ฟิลด์ดัชนีลำดับตามค่าเท่ากับตามด้วยช่วงที่เลือกมากที่สุดหรือฟิลด์อสมการ

Cloud Firestore ใ��้ช่องด้านซ้ายสุดของดัชนีผสมเพื่อปฏิบัติตามข้อกำหนด ข้อจำกัดความเท่าเทียมและข้อจำกัดช่วงหรืออสมการ ถ้ามี ในฟิลด์แรก ของการค้นหา orderBy() ข้อจำกัดเหล่านี้อาจทำให้จำนวนดัชนีลดลงได้ รายการที่ Cloud Firestore สแกน Cloud Firestore ใช้ช่องที่เหลือ ของดัชนีเพื่อตอบสนองข้อจำกัดอื่นๆ ของช่วงหรืออสมการของการค้นหา เหล่านี้ ข้อจำกัดไม่ลดจำนวนรายการดัชนีที่ Cloud Firestore สแกน แต่ให้กรองเอกสารที่ไม่ตรงกันออก เพื่อให้จำนวนเอกสารที่มี ที่ส่งคืนให้ลูกค้าก็ลดลง

ดูข้อมูลเพิ่มเติมเกี่ยวกับการสร้างดัชนีที่มีประสิทธิภาพได้ที่พร็อพเพอร์ตี้ดัชนี

ช่องคำสั่งซื้อตามลำดับจากมากไปน้อยของการเลือกข้อจำกัดการค้นหา

เพื่อให้ Cloud Firestore เลือกดัชนีที่ดีที่สุดสำหรับการค้นหาของคุณ ระบุอนุประโยค orderBy() ที่เรียงลำดับช่องจากน้อยไปหามากของคำค้นหา ข้อจำกัดการเลือก การเลือกที่สูงขึ้นจะตรงกับชุดย่อยที่เล็กลงของ แต่การเลือกเอกสารที่ต่ำกว่าจะจับคู่กับเอกสารชุดย่อยที่มีขนาดใหญ่กว่า ตรวจสอบว่า คุณเลือกช่องช่วงหรืออสมการซึ่งมีการเลือกสูงกว่าในดัชนีก่อนหน้านี้ เรียงลำดับมากกว่าช่องที่มีการเลือกต่ำ

เพื่อลดจำนวนเอกสารที่ Cloud Firestore สแกนและแสดงผล เครือข่าย คุณควรเรียงลำดับฟิลด์ในลำดับจากน้อยไปหามากเสมอ ข้อจำกัดการเลือก หากชุดผลลัพธ์ไม่อยู่ในลำดับที่กำหนดและ ชุดผลลัพธ์ควรมีขนาดเล็ก คุณสามารถใช้ตรรกะฝั่งไคลเอ็นต์เพื่อ สั่งซื้ออีกครั้งตามความคาดหวังด้านการสั่งซื้อ

ตัวอย่างเช่น สมมติว่าคุณต้องการค้นหากลุ่มพนักงานเพื่อค้นหา พนักงานในสหรัฐอเมริกาที่มีเงินเดือนมากกว่า $100,000 และเรียงลำดับผลลัพธ์ภายในปี ประสบการณ์การใช้งานของพนักงาน หากคุณมีพนักงานเพียงไม่กี่คนเท่านั้นที่จะมี���งินเดือน มากกว่า $100,000 วิธีที่มีประสิทธิภาพมากที่สุดในการเขียนคำค้นหามีดังนี้

Java

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .orderBy("salary")
  .get()
  .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
          // Order results by `experience`
        }
    });;

Node.js

const querySnapshot = await db.collection('employees')
                              .where("salary", ">", 100000)
                              .orderBy("salary")
                              .get();

// Order results by `experience`

Python

results = db.collection("employees")
            .where("salary", ">", 100000)
            .order_by("salary")
            .stream()

// Order results by `experience`

ขณะที่การเพิ่มการจัดลำดับใน experience ลงในคำค้นหาก็จะได้ผลลัพธ์ชุดเดียวกัน และพยายามเรียงลำดับผลลัพธ์ใหม่กับไคลเอ็นต์ ข้อความค้นหาอาจ อ่านรายการดัชนีที่ไม่เกี่ยวข้องมากกว่าข้อความค้นหาก่อนหน้านี้ นั่นเป็นเพราะ Cloud Firestore จะเลือกดัชนีที่มีคำนำหน้าช่องดัชนีตรงกับค่า ตามลำดับของข้อความค้นหา หากเพิ่ม experience ลงในคำสั่งซื้อตามวรรค Cloud Firestore จะเลือกดัชนี (experience [...], salary [...]) สำหรับการคำนวณผลการค้นหา เนื่องจากไม่มีข้อจำกัดอื่นๆ experience Cloud Firestore จะอ่านรายการดัชนีทั้งหมดของ employees คอลเล็กชันก่อนใช้ตัวกรอง salary เพื่อค้นหาขั้นสุดท้าย ชุดผลลัพธ์ ซึ่งหมายความว่ารายการดัชนีที่ไม่ตรงกับ salary ตัวกรองจะยังคงอ่านอยู่ ซึ่งจะเพิ่มเวลาในการตอบสนองและค่าใช้จ่ายของข้อความค้นหา

ราคา

ระบบจะเรียกเก็บเงินสำหรับคำค้นหาที่มีตัวกรองช่วงและค่าที่เท่ากันในหลายช่องโดยอิงตาม เอกสารที่อ่านและจัดทำดัชนีรายการที่อ่านแล้ว

ดูรายละเอียดเพิ่มเติมได้ที่หน้าราคา

ข้อจำกัด

นอกเหนือจากข้อจำกัดของการค้นหาแล้ว โปรดศึกษาข้อจำกัดต่อไปนี้ก่อน โดยใช้คำค้นหาที่มีตัวกรองช่วงและอสมการในหลายช่อง ดังนี้

  • การค้นหาที่มีตัวกรองช่วงหรืออสมการใน��่องเอกสารและมีเพียงความเท่ากันเท่านั้น ไม่สนับสนุนข้อจำกัดในคีย์เอกสาร (__name__)
  • Cloud Firestore จำกัดจำนวนช่องช่วงหรืออสมการเป็น 10 เพื่อป้องกันไม่ให้คำค้นหามีราคาแพงเกินไป ที่จะเรียกใช้

ขั้นตอนถัดไป