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

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 สแกน แต่กรองเอกสารที่ไม่ตรงกันออกเพื่อลดจำนวนเอกสารที่แสดงต่อไคลเอ็นต์

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

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

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

หากต้องการลดจำนวนเอกสารที่ 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 ช่อง การดำเนินการนี้จะช่วยป้องกันไม่ให้การค้นหามีค่าใช้จ่ายสูงเกินไป

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