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

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)

متابعة

   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 حقول. وذلك لمنع أن تصبح طلبات البحث باهظة التكلفة جدًا.

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