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

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

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

تحسين طلبات البحث باستخدام أداة Query Explain

لتحديد ما إذا كان طلب البحث والفهارس في أفضل حالاتها، يمكنك استخدام أداة 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");

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

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

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