एक से ज़्यादा फ़ील्ड पर, रेंज और इनक्वलिटी फ़िल्टर के साथ क्वेरी करने से जुड़ी खास जानकारी

Cloud Firestore, एक क्वेरी में कई फ़ील्ड पर रेंज और असमानता वाले फ़िल्टर इस्तेमाल करने की सुविधा देता है. आपके पास कई फ़ील्ड पर रेंज और असमानता की शर्तें लागू करने का विकल्प होता है. साथ ही, फ़िल्टर करने के बाद की जाने वाली कार्रवाइयों के लॉजिक को Cloud Firestore को सौंपकर, ऐप्लिकेशन को आसानी से डेवलप किया जा सकता है.

कई फ़ील्ड पर रेंज और असमिका वाले फ़िल्टर

नीचे दी गई क्वेरी में,जनसंख्या और घनत्व के लिए रेंज फ़िल्टर का इस्तेमाल किया गया है. इससे उन सभी शहरों की जानकारी मिलती है जहां जनसंख्या 10 लाख से ज़्यादा है और जनसंख्या घनत्व,इलाके की हर यूनिट के हिसाब से 10,000 से कम है.

वेब वर्शन 9 मॉड्यूलर

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

इंडेक्स करने से जुड़ी बातें

क्वेरी चलाने से पहले, क्वेरी और Cloud Firestore डेटा मॉडल के बारे में पढ़ें.

Cloud Firestore में, क्वेरी का ORDER BY क्लॉज़ यह तय करता है कि क्वेरी को पूरा करने के लिए किन इंडेक्स का इस्तेमाल किया जा सकता है. उदाहरण के लिए, ORDER BY a ASC, b ASC क्वेरी के लिए, a ASC, b ASC फ़ील्ड पर कंपोज़िट इंडेक्स की ज़रूरत होती है.

Cloud Firestore क्वेरी की परफ़ॉर्मेंस और लागत को ऑप्टिमाइज़ करने के लिए, इंडेक्स में फ़ील्ड के क्रम को ऑप्टिमाइज़ करें. इसके लिए, पक्का करें कि आपका इंडेक्स बाएं से दाएं क्रम में हो, ताकि क्वेरी ऐसे डेटासेट में बदल जाए जो इंडेक्स की गैर-ज़रूरी एंट्री को स्कैन करने से रोकता है.

मान लें कि आपको कर्मचारियों के कलेक्शन में खोज करनी है. आपको ऐसे कर्मचारियों को ढूंढना है जो अमेरिका में काम करते हैं, जिनकी सैलरी 1,00,000 डॉलर से ज़्यादा है, और जिनका अनुभव एक साल से ज़्यादा है. डेटासेट को समझने के बाद, आपको पता चलता है कि सैलरी की शर्त, अनुभव की शर्त से ज़्यादा चुनिंदा है. सबसे सही इंडेक्स (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 स्कैन करता है. हालांकि, इनसे मेल न खाने वाले दस्तावेज़ों को फ़िल्टर किया जाता है, ताकि क्लाइंट को लौटाए जाने वाले दस्तावेज़ों की संख्या कम हो जाए.

असरदार इंडेक्स बनाने के बारे में ज़्यादा जानने के लिए, इंडेक्स प्रॉपर्टी देखें.

क्वेरी की शर्तों के हिसाब से, ऑर्डर फ़ील्ड को घटते क्रम में लगाना

यह पक्का करने के लिए कि Cloud Firestore आपकी क्वेरी के लिए सबसे सही इंडेक्स चुनता है, orderBy() क्लॉज़ तय करें. यह क्लॉज़, क्वेरी की शर्त के हिसाब से फ़ील्ड को घटते क्रम में लगाता है. ज़्यादा सेलेक्टिविटी, दस्तावेज़ों के छोटे सबसेट से मेल खाती है. वहीं, कम सेलेक्टिविटी, दस्तावेज़ों के बड़े सबसेट से मेल खाती है. पक्का करें कि इंडेक्स के क्रम में, ज़्यादा चुनिंदा फ़ील्ड के तौर पर रेंज या असमानता वाले फ़ील्ड को कम चुनिंदा फ़ील्ड से पहले चुना गया हो.

Cloud Firestore नेटवर्क पर स्कैन किए गए और दिखाए गए दस्तावेज़ों की संख्या को कम करने के लिए, आपको हमेशा फ़ील्ड को क्वेरी की शर्त के हिसाब से घटते क्रम में रखना चाहिए. अगर नतीजों का सेट, ज़रूरी क्रम में नहीं है और नतीजों का सेट छोटा होने की उम्मीद है, तो क्लाइंट-साइड लॉजिक लागू करके, उसे अपनी उम्मीद के मुताबिक फिर से क्रम में लगाया जा सकता है.

उदाहरण के लिए, मान लें कि आपको कर्मचारियों के कलेक्शन में खोज करनी है. आपको अमेरिका में रहने वाले ऐसे कर्मचारियों की जानकारी चाहिए जिनका वेतन 1,00,000 डॉलर से ज़्यादा है. साथ ही, आपको कर्मचारियों के अनुभव के हिसाब से नतीजों को क्रम से लगाना है. अगर आपको लगता है कि सिर्फ़ कुछ कर्मचारियों का वेतन 1,00,000 डॉलर से ज़्यादा होगा, तो क्वेरी लिखने का सबसे सही तरीका यह है:

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 फ़िल्टर की शर्तों को पूरा नहीं करती हैं. हालांकि, उन्हें अब भी पढ़ा जाता है. इससे क्वेरी की लेटेन्सी और लागत बढ़ जाती है.

कीमत

एक से ज़्यादा फ़ील्ड पर रेंज और असमानता वाले फ़िल्टर वाली क्वेरी के लिए, पढ़े गए दस्तावेज़ों और इंडेक्स एंट्री के आधार पर बिलिंग की जाती है.

ज़्यादा जानकारी के लिए, कीमत पेज देखें.

सीमाएं

क्वेरी से जुड़ी सीमाओं के अलावा, एक से ज़्यादा फ़ील्ड पर रेंज और असमानता वाले फ़िल्टर के साथ क्वेरी इस्तेमाल करने से पहले, इन सीमाओं पर ध्यान दें:

  • दस्तावेज़ के फ़ील्ड पर रेंज या असमानता वाले फ़िल्टर और दस्तावेज़ के मुख्य फ़ील्ड (__name__) पर सिर्फ़ समानता की शर्तें लागू करने वाली क्वेरी काम नहीं करती हैं.
  • Cloud Firestore, रेंज या असमानता वाले फ़ील्ड की संख्या को 10 तक सीमित करता है. ऐसा इसलिए किया जाता है, ताकि क्वेरी चलाने में बहुत ज़्यादा खर्च न हो.

आगे क्या करना है