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

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

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

नीचे दी गई क्वेरी में, उम्र और लंबाई के लिए रेंज फ़िल्टर इस्तेमाल करके वे सभी उपयोगकर्ता दिखाए जाते हैं जिनकी उम्र 35 से ज़्यादा और लंबाई 60 से 70 के बीच है.

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

  const q = query(
      collection(db, "users"),
      where('age', '>', 35),
      where('height', '>', 60),
      where('height', '<', 70)
    );

Swift

 let query = db.collection("users")
   .whereField("age", isGreaterThan: 35)
   .whereField("height", isGreaterThan: 60)
   .whereField("height", isLessThan: 70)

Objective-C

 FIRQuery *query = 
  [[[[self.db collectionWithPath:@"users"]
 queryWhereField:@"age" isGreaterThan:@35]
    queryWhereField:@"height" isGreaterThan:@60] 
        queryWhereField:@"height" isLessThan:@70];

Java Android

 Query query = db.collection("users")
  .whereGreaterThan("age", 35)
  .whereGreaterThan("height", 60)
  .whereLessThan("height", 70);

Kotlin+KTX Android

 val query = db.collection("users")
  .whereGreaterThan("age", 35)
  .whereGreaterThan("height", 60)
  .whereLessThan("height", 70)

Java

  db.collection("users")
    .whereGreaterThan("age", 35)
    .whereGreaterThan("height", 60)
    .whereLessThan("height", 70);

Node.js के लिए

db.collection("users")
  .where('age', '>', 35),
  .where('height', '>', 60),
  .where('height', '<', 70)

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

अपनी क्वेरी चलाना शुरू करने से पहले, पक्का करें कि आपने क्वेरी और 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 जिन दस्तावेज़ों को स्कैन करके नेटवर्क पर भेजता है उनकी संख्या कम करने के लिए, आपको हमेशा क्वेरी कंस्ट्रेंट सेलेक्टिविटी के घटते क्रम में फ़ील्ड को क्रम में लगाना चाहिए. अगर नतीजे का सेट ज़रूरी क्रम में नहीं है और नतीजों का सेट छोटा होना चाहिए, तो क्लाइंट-साइड लॉजिक को लागू करके इसे क्रम में लगाया जा सकता है.

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

कीमत

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

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

सीमाएं

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

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

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