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

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

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

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

कीमत

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

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

सीमाएं

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

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

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