Cloud Firestore รองรับการใช้ตัวกรองช่วงและความไม่เท่ากันในหลายช่องในการค้นหาเดียว คุณสามารถมีเงื่อนไขช่วงและความไม่เท่ากันในหลายฟิลด์ และลดความซับซ้อนในการพัฒนาแอปพลิเคชันโดยมอบสิทธิ์การใช้งานตรรกะหลังการกรองให้กับ Cloud Firestore
ตัวกรองช่วงและอสมการในหลายช่อง
การค้นหาต่อไปนี้ใช้ตัวกรองช่วงกับประชากรและความหนาแน่นเพื่อแสดงผลเมืองทั้งหมดที่มีประชากรมากกว่า 1,000,000 คนและความหนาแน่นของประชากรน้อยกว่า 10,000 คนต่อหน่วยพื้นที่
Web เวอร์ชัน 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
C#
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);
ข้อควรพิจารณาเกี่ยวกับการจัดทำดัชนี
ก่อนเรียกใช้การค้นหา โปรดอ่านเกี่ยวกับ [การค้นหา][1] และ Cloud Firestore [โมเดลข้อมูล][2]
ใน 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 สแกน แต่จะกรองเอกสารที่ไม่ตรงกันออกเพื่อให้จำนวนเอกสารที่ส่งกลับไปยังไคลเอ็นต์ลดลง
ดูข้อมูลเพิ่มเติมเกี่ยวกับการสร้างดัชนีที่มีประสิทธิภาพได้ที่ [พร็อพเพอร์ตี้ดัชนี][4]
จัดเรียงฟิลด์ตามลำดับความสามารถในการเลือกข้อจำกัดของคำค้นหาจากมากไปน้อย
เพื่อให้แน่ใจว่า 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 จะเลือกดัชนีที่มีคำนำหน้าช่องดัชนีตรงกับส่วนคำสั่ง order by ของการค้นหาเสมอ หากเพิ่ม experience ลงในคำสั่งตามส่วนคำสั่ง
Cloud Firestore จะเลือกดัชนี (experience [...], salary [...])
เพื่อคำนวณผลการค้นหา เนื่องจากไม่มีข้อจำกัดอื่นๆ ใน experience Cloud Firestore จะอ่านรายการดัชนีทั้งหมดของคอลเล็กชัน employees ก่อนใช้ตัวกรอง salary เพื่อค้นหาชุดผลลัพธ์สุดท้าย ซึ่งหมายความว่าระบบจะยังคงอ่านรายการดัชนีที่ไม่เป็นไปตามตัวกรอง salary ซึ่งจะเพิ่มเวลาในการตอบสนองและค่าใช้จ่ายในการค้นหา
ราคา
ระบบจะเรียกเก็บเงินสำหรับการค้นหาที่มีตัวกรองช่วงและตัวกรองอสมการในหลายฟิลด์โดยอิงตามเอกสารที่อ่านและรายการดัชนีที่อ่าน
ดูข้อมูลโดยละเอียดได้ที่หน้า[ราคา][5]
ข้อจำกัด
นอกเหนือจาก [ข้อจำกัดของคำค้นหา][6] แล้ว โปรดทราบข้อจำกัดต่อไปนี้ก่อนใช้คำค้นหาที่มีตัวกรองช่วงและความไม่เท่ากันในหลายฟิลด์
- ไม่รองรับการค้นหาที่มีตัวกรองช่วงหรือความไม่เท่ากันในช่องเอกสารและข้อจำกัดความเท่ากันในคีย์เอกสาร
(__name__)เท่านั้น - Cloud Firestore จำกัดจำนวนช่องช่วงหรือช่องอสมการไว้ที่ 10 ช่อง เพื่อป้องกันไม่ให้การค้นหามีค่าใช้จ่ายสูงเกินไป
ขั้นตอนถัดไป
- ดูข้อมูลเกี่ยวกับ[การเพิ่มประสิทธิภาพการค้นหา][3]
- ดูข้อมูลเพิ่มเติมเกี่ยวกับ[การค้นหาแบบง่ายและแบบผสม][8]
- ทำความเข้าใจวิธีที่ [Cloud Firestore ใช้อินเด็กซ์][9]
[1]: /docs/firestore/query-data/get-data [2]: /docs/firestore/data-model [3]: /docs/firestore/query-data/multiple-range-optimize-indexes [4]: /docs/firestore/concepts/index-overview#index_properties [5]: /docs/firestore/pricing [6]: /docs/firestore/query-data/queries#query_limitations [7]: https://en.wikipedia.org/wiki/Disjunctive_normal_form [8]: /docs/firestore/query-data/queries [9]: /docs/firestore/concepts/index-overview [10]: /docs/firestore/query-data/multiple-range-optimize-indexes