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

يتيح 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