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

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

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

تحسين طلبات البحث باستخدام "شرح طلب البحث"

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

جافا

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) على النحو التالي:

جافا

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

يفحص الاستعلام 95000 إدخال فهرس فقط لعرض 5 مستندات فقط. نظرًا لعدم استيفاء إسناد طلب البحث، تتم قراءة عدد كبير من إدخالات الفهرس، ولكن تتم تصفيتها.

// 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.

جافا

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"
        }
    }
}

ما هي الخطوات التالية؟