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

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

قبل تحسين طلبات البحث، اطّلِع على المفاهيم ذات الصلة.

تحسين طلبات البحث باستخدام ميزة "تفسير طلب البحث"

لتحديد ما إذا كان طلب البحث والفهارس مثالية، يمكنك استخدام Query Explain للحصول على ملخّص خطة طلب البحث وإحصاءات التنفيذ الخاصة بطلب البحث:

Java

Query q = db.collection("employees").whereGreaterThan("salary",
100000).whereGreaterThan("experience", 0);

ExplainResults<QuerySnapshot> explainResults = q.explain(ExplainOptions.builder().analyze(true).build()).get();
ExplainMetrics metrics = explainResults.getMetrics();

PlanSummary planSummary = metrics.getPlanSummary();
ExecutionStats executionStats = metrics.getExecutionStats();

System.out.println(planSummary.getIndexesUsed());
System.out.println(stats.getResultsReturned());
System.out.println(stats.getExecutionDuration());
System.out.println(stats.getReadOperations());
System.out.println(stats.getDebugStats());

Node.js

let q = db.collection("employees")
      .where("salary", ">", 100000)
      .where("experience", ">",0);

let options = { analyze : 'true' };
let explainResults = await q.explain(options);

let planSummary = explainResults.metrics.planSummary;
let stats = explainResults.metrics.executionStats;

console.log(planSummary);
console.log(stats);

يوضّح المثال التالي كيف يؤدي استخدام الترتيب الصحيح للفهرس إلى تقليل عدد إدخالات الفهرس التي يفحصها Cloud Firestore.

طلبات البحث البسيطة

في المثال السابق لمجموعة من الموظفين، يكون طلب البحث البسيط الذي يتم تشغيله باستخدام الفهرس (experience ASC, salary ASC) على النحو التالي:

Java

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .whereGreaterThan("experience", 0)
  .orderBy("experience")
  .orderBy("salary");

يفحص طلب البحث 95,000 إدخال في الفهرس لعرض خمسة مستندات فقط. بما أنّ دالة الاستعلام لا يتم استيفاؤها، تتم قراءة عدد كبير من إدخالات الفهرس ولكن تتم فلترتها.

// Output query planning info
{
    "indexesUsed": [
        {
            "properties": "(experience ASC, salary ASC, __name__ ASC)",
            "query_scope": "Collection"
        }
    ],

    // Output Query Execution Stats
    "resultsReturned": "5",
    "executionDuration": "2.5s",
    "readOperations": "100",
    "debugStats": {
        "index_entries_scanned": "95000",
        "documents_scanned": "5",
        "billing_details": {
            "documents_billable": "5",
            "index_entries_billable": "95000",
            "small_ops": "0",
            "min_query_cost": "0"
        }
    }
}

يمكنك أن تستنتج من الخبرة في المجال أن معظم الموظفين سيكون لديهم على الأقل بعض الخبرة ولكن القليل منهم سيحصل على راتب يزيد عن 100000. بناءً على هذه المعلومة، يمكنك ملاحظة أنّ القيد salary أكثر انتقائية من القيد experience. للتأثير في الفهرس الذي يستخدمه Cloud Firestore لتنفيذ طلب البحث، حدِّد عبارة orderBy تطلب قيد salary قبل قيد experience.

Java

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .whereGreaterThan("experience", 0)
  .orderBy("salary")
  .orderBy("experience");

عند استخدام عبارة orderBy() بشكل صريح لإضافة المسندات، يستخدم Cloud Firestore فهرس (salary ASC, experience ASC) لتشغيل طلب البحث. بما أنّ انتقائية فلتر النطاق الأول أعلى في طلب البحث هذا مقارنةً بطلب البحث السابق، يتم تنفيذ طلب البحث بشكل أسرع وأكثر فعالية من حيث التكلفة.

// Output query planning info
{
    "indexesUsed": [
        {
            "properties": "(salary ASC, experience ASC, __name__ ASC)",
            "query_scope": "Collection"
        }
    ],

    // Output Query Execution Stats
    "resultsReturned": "5",
    "executionDuration": "0.2s",
    "readOperations": "6",
    "debugStats": {
        "index_entries_scanned": "1000",
        "documents_scanned": "5",
        "billing_details": {
            "documents_billable": "5",
            "index_entries_billable": "1000",
            "small_ops": "0",
            "min_query_cost": "0"
        }
    }
}

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