نمای کلی پُرسمان با فیلترهای گستره و نابرابری در چند فیلد

Cloud Firestore از استفاده از فیلترهای محدوده و نابرابری در چندین فیلد در یک پُرسمان پشتیبانی می‌کند. می‌توانید شرایط محدوده و نابرابری را در چندین فیلد داشته باشید و توسعه برنامه خود را با واگذاری پیاده‌سازی منطق پس‌فیلتر به Cloud Firestore ساده کنید.

فیلترهای محدوده و نامساوی در چندین فیلد

پرس‌وجو زیر از فیلترهای محدوده روی جمعیت و تراکم استفاده می‌کند تا همه شهرهایی را که جمعیت آن‌ها بیشتر از ۱٬۰۰۰٬۰۰۰ نفر و تراکم جمعیت آن‌ها کمتر از ۱۰٬۰۰۰ نفر در واحد مساحت است برگرداند.

نسخه وب ۹ مدولار

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)

جاوا

db.collection("cities")
  .whereGreaterThan("population", 1000000)
  .whereLessThan("density", 10000);

Node.js

db.collection("cities")
  .where('population', '>', 1000000),
  .where('density', '<', 10000)

پایتون

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

سی شارپ

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، ترتیب فیلدها را در نمایه بهینه‌سازی کنید. برای انجام این کار، مطمئن شوید که نمایه‌تان از چپ به راست مرتب شده باشد تا پُرسمان به مجموعه داده‌ای تبدیل شود که از اسکن کردن ورودی‌های غیرضروری نمایه جلوگیری می‌کند.

فرض کنید می‌خواهید در مجموعه‌ای از کارمندان جستجو کنید و کارمندان ایالات متحده را که حقوقشان بیشتر از ۱۰۰٬۰۰۰ دلار است و تعداد سال‌های تجربه آن‌ها بیشتر از ۰ است پیدا کنید. براساس درک شما از مجموعه داده، می‌دانید که محدودیت حقوق گزینشی‌تر از محدودیت تجربه است. شاخص ایده‌آل که تعداد اسکن‌های شاخص را کاهش می‌دهد (salary [...], experience [...]) است. بنابراین، پُرسمانی که سریع و مقرون‌به‌صرفه باشد، salary را قبل‌از experience سفارش می‌دهد و به‌صورت زیر خواهد بود:

جاوا

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

پایتون

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 اسکن می‌کند و ازطریق شبکه برمی‌گرداند، همیشه باید فیلدها را به‌ترتیب نزولی گزینش‌پذیری محدودیت پُرسمان مرتب کنید. اگر مجموعه نتایج به ترتیب موردنیاز نیست و انتظار می‌رود مجموعه نتایج کوچک باشد، می‌توانید منطق سمت کارخواه را برای مرتب‌سازی مجدد آن طبق انتظار سفارش خود پیاده‌سازی کنید.

برای مثال، فرض کنید می‌خواهید در مجموعه‌ای از کارمندان جستجو کنید تا کارمندان ایالات متحده را که حقوقشان بیشتر از ۱۰۰٬۰۰۰ دلار است پیدا کنید و نتایج را براساس سال‌های تجربه کارمند مرتب کنید. اگر انتظار دارید فقط تعداد کمی از کارمندان حقوقی بیشتر از ۱۰۰٬۰۰۰ دلار داشته باشند، کارآمدترین روش برای نوشتن پُرسمان به‌صورت زیر است:

جاوا

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`

پایتون

results = db.collection("employees")
            .where("salary", ">", 100000)
            .order_by("salary")
            .stream()

// Order results by `experience`

While adding an ordering on experience to the query will yield the same set of documents and obviate re-ordering the results on the clients, the query may read many more extraneous index entries than the earlier query. دلیلش این است که Cloud Firestore همیشه نمایه‌ای را ترجیح می‌دهد که پیشوند فیلدهای نمایه‌اش با بند order by پُرسمان مطابقت داشته باشد. اگر experience به عبارت order by اضافه شده بود، Cloud Firestore نمایه (experience [...], salary [...]) را برای محاسبه نتایج پُرسمان انتخاب می‌کرد. ازآنجایی‌که هیچ محدودیت دیگری برای experience وجود ندارد، Cloud Firestore همه ورودی‌های نمایه مجموعه employees را قبل‌از اعمال فیلتر salary برای یافتن مجموعه نتایج نهایی خواهد خواند. این یعنی ورودی‌های نمایه‌ای که فیلتر salary را برآورده نمی‌کنند همچنان خوانده می‌شوند، بنابراین تأخیر و هزینه پُرسمان افزایش می‌یابد.

قیمت‌گذاری

پرس‌وجوهای دارای فیلترهای محدوده و نابرابری در چندین فیلد براساس اسناد خوانده‌شده و ورودی‌های نمایه خوانده‌شده صورت‌حساب می‌شوند.

برای اطلاعات دقیق، به صفحه [قیمت‌گذاری][5] مراجعه کنید.

محدودیت‌ها

علاوه‌بر [محدودیت‌های پُرسمان][6]، قبل‌از استفاده از پُرسمان‌های دارای فیلترهای محدوده و نابرابری در چندین فیلد، به محدودیت‌های زیر توجه کنید:

  • پرس‌وجوهایی که فیلترهای گستره یا نابرابری در فیلدهای سند دارند و فقط محدودیت‌های برابری در کلید سند (__name__) دارند پشتیبانی نمی‌شوند.
  • Cloud Firestore تعداد فیلدهای محدوده یا نابرابری را به ۱۰ محدود می‌کند. این کار برای جلوگیری از گران شدن بیش‌ازحد پُرسمان‌ها برای اجرا است.

حالا چه می‌شود

  • درباره [بهینه‌سازی پُرسمان‌هایتان][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