نظرة عامة على طلب البحث الذي يتضمّن فلاتر النطاق وعدم المساواة في حقول متعدّدة

تتيح Cloud Firestore استخدام فلاتر النطاق وعدم المساواة على حقول متعددة في طلب بحث واحد. يمكنك تطبيق شروط النطاق وعدم المساواة على حقول متعددة وتسهيل عملية تطوير تطبيقك من خلال تفويض تنفيذ منطق ما بعد الفلترة إلى Cloud Firestore.

فلاتر النطاق والمقارنة على حقول متعددة

يستخدم طلب البحث التالي فلاتر نطاق على عدد السكان والكثافة السكانية لعرض جميع المدن التي يزيد عدد سكانها عن 1,000,000 نسمة وتقل الكثافة السكانية فيها عن 10,000 نسمة لكل وحدة مساحة.

Web version 9 modular

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 يفضّل دائمًا فهرسًا يتطابق فيه بادئة حقول الفهرس مع عبارة order by في طلب البحث. في حال تمت إضافة experience إلى عبارة order by، سيتم اختيار الفهرس (experience [...], salary [...]) لحساب نتائج طلب البحث.Cloud Firestore بما أنّه لا توجد قيود أخرى على experience، سيقرأ Cloud Firestore جميع إدخالات الفهرس الخاصة بمجموعة employees قبل تطبيق فلتر salary للعثور على مجموعة النتائج النهائية. وهذا يعني أنّه سيتمّ قراءة إدخالات الفهرس التي لا تستوفي معايير الفلترة salary، ما يؤدي إلى زيادة وقت الاستجابة وتكلفة الاستعلام.

الأسعار

يتم تحصيل رسوم الاستعلامات التي تتضمّن فلاتر النطاق وعدم المساواة في حقول متعدّدة استنادًا إلى عدد المستندات التي تمّت قراءتها وإدخالات الفهرس التي تمّت قراءتها.

للحصول على معلومات تفصيلية، اطّلِع على صفحة الأسعار.

القيود

بالإضافة إلى قيود طلبات البحث، يُرجى ملاحظة القيود التالية قبل استخدام طلبات البحث مع فلاتر النطاق وعدم المساواة في حقول متعددة:

  • لا تتوفّر طلبات البحث التي تتضمّن فلاتر نطاق أو عدم مساواة في حقول المستندات وقيود مساواة فقط في مفتاح المستند (__name__).
  • يحدّ Cloud Firestore من عدد حقول النطاق أو عدم المساواة إلى 10. ويتم ذلك لمنع الاستعلامات من أن تصبح مكلفة جدًا عند تنفيذها.

الخطوات التالية