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

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 [...]) होगा. इसलिए, वह क्वेरी जो तेज़ और किफ़ायती होगी, experience से पहले salary को क्रम में लगाएगी और कुछ इस तरह दिखेगी:

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 स्कैन करता है. हालांकि, ये शर्तें, मेल न खाने वाले दस्तावेज़ों को फ़िल्टर कर देती हैं, ताकि क्लाइंट को लौटाए जाने वाले दस्तावेज़ों की संख्या कम हो जाए.

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

क्वेरी की शर्त की चुनिंदाता के घटते क्रम में फ़ील्ड को क्रम में लगाएं

यह पक्का करने के लिए कि 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 हमेशा ऐसे इंडेक्स को प्राथमिकता देता है जिसके इंडेक्स फ़ील्ड का प्रीफ़िक्स, क्वेरी के क्रम के हिसाब से मेल खाता हो. अगर experience क्रम के हिसाब से क्लॉज़ में जोड़ा जाता है, तो Cloud Firestore क्वेरी के नतीजों की गिनती करने के लिए, (experience [...], salary [...]) इंडेक्स चुनेगा. experience पर कोई अन्य शर्त न होने की वजह से, Cloud Firestore फ़ाइनल नतीजों का सेट ढूंढने के लिए, salary फ़िल्टर लागू करने से पहले, employees कलेक्शन की सभी इंडेक्स एंट्री पढ़ेगा. इसका मतलब है कि इंडेक्स की वे एंट्री भी पढ़ी जाती हैं जो salary फ़िल्टर की शर्त को पूरा नहीं करती हैं. इससे, क्वेरी की लेटेन्सी और लागत बढ़ जाती है.

कीमत

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

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

सीमाएं

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

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

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