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

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

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

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

الإصدار 9 من حزمة تطوير البرامج (SDK) للويب المتعددة الوحدات

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);

ملاحظات حول الفهرسة

قبل تشغيل طلبات البحث، يُرجى الاطّلاع على [طلبات البحث][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 دولار أمريكي وترتيب النتائج حسب سنة خبرة الموظف. إذا كنت تتوقع أن يحصل عدد قليل فقط من الموظفين على رواتب أكبر من 100000 دولار، فإن الطريقة الأكثر فعالية لكتابة الاستعلام هي كما يلي:

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

الأسعار

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

للحصول على معلومات تفصيلية، يُرجى الاطّلاع على صفحة [الأسعار][5].

القيود

Apart from the [query limitations][6], note the following limitations before using queries with range and inequality filters on multiple fields:

  • لا يمكن تنفيذ طلبات البحث التي تتضمّن فلاتر نطاق أو فلاتر عدم مساواة في حقول المستندات وقيود مساواة فقط على مفتاح المستند (__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