फायरस्टार क्वेरी सबकोलेक्शन


125

मुझे लगा कि मैं पढ़ता हूं कि आप नए फायरबेस फायरस्टार के साथ सबकोलेक्शन को क्वेरी कर सकते हैं, लेकिन मुझे कोई उदाहरण नहीं दिखता। उदाहरण के लिए मेरे पास निम्नलिखित तरीके से मेरा फायरस्टार सेटअप है:

  • नृत्य [संग्रह]
    • danceName
    • गाने [संग्रह]
      • गाने का नाम

मैं क्वेरी कैसे कर पाऊंगा "सभी नृत्यों का पता लगाएं जहां songName == 'X'"


1
क्या यह अभी तक फायरस्टार, वर्ष 2020 समर्थित है?
सजनमहा

जवाबों:


148

अपडेट 2019-05-07

आज हमने संग्रह समूह क्वेरीज़ जारी कीं , और ये आपको सबकोइलेक्शन में क्वेरी करने की अनुमति देते हैं।

इसलिए, उदाहरण के लिए वेब एसडीके में:

db.collectionGroup('Songs')
  .where('songName', '==', 'X')
  .get()

यह किसी भी संग्रह में दस्तावेजों से मेल खाता है जहां संग्रह पथ का अंतिम भाग 'गीत' है।

आपका मूल प्रश्न नाच को खोजने के बारे में था जहां गीतनाम == 'एक्स', और यह अभी भी सीधे संभव नहीं है, हालांकि, प्रत्येक गीत के लिए जो आप से मेल खाते हैं, आप उसके माता-पिता को लोड कर सकते हैं।

मूल उत्तर

यह एक ऐसी विशेषता है जो अभी तक मौजूद नहीं है। इसे एक "संग्रह समूह क्वेरी" कहा जाता है और आपको सभी गीतों की क्वेरी करने की अनुमति देगा चाहे कोई भी नृत्य उनमें निहित हो। यह ऐसी चीज है जिसका हम समर्थन करना चाहते हैं, लेकिन जब यह आ रही है तो इसका कोई ठोस समय नहीं है।

इस बिंदु पर वैकल्पिक संरचना गीतों को एक शीर्ष-स्तरीय संग्रह बनाने के लिए है और जो गीत को नृत्य करता है वह गीत की एक संपत्ति का एक हिस्सा है।


147
यह बेहतर होगा कि फायरस्टार देव टीम ने ASAP के सबकोक्लेक्शन प्रश्नों को लागू किया। आखिरकार, 'अधिक शक्तिशाली प्रश्न' फायरस्टार मैनुअल के अनुसार प्रमुख विक्रय बिंदुओं में से एक है। अभी, फायरस्टार बिना पहियों के पोर्श की तरह है।
३38 बजे आर्ने वोल्फ्रैम नोव

21
हम मानते हैं! दिन में बस कुछ घंटों की संख्या है :-)।
गिल गिलबर्ट

20
मुझे समझ में नहीं आ रहा है कि अगर लोग फायरबेस सीमित हैं तो लोग क्या भुगतान करेंगे? यहां तक ​​कि बैकएंडलेस की तरह लगता है कि फायरबेस की तुलना में अधिक कार्यक्षमता है। और फायरबेस इतना लोकप्रिय क्यों है? लगता है लोग पागल हो गए
nzackoya

15
इस सुविधा की अत्यधिक आवश्यकता है वरना लोग विकल्प ढूंढना शुरू कर देंगे, यहां तक ​​कि हमारे पास मिलने की समय सीमा भी है। : P
JD-V

13
हमें इस सुविधा की आवश्यकता है। इसे जारी करने के लिए समय पर पट्टे पर हमें तैयार रहने में मदद मिलेगी।
संजाया पनिग्रही

22

अद्यतन अब फायरस्टार सरणी-समाहित करता है

इन दस्तावेजों का होना

    {danceName: 'Danca name 1', songName: ['Title1','Title2']}
    {danceName: 'Danca name 2', songName: ['Title3']}

इस तरह से करो

collection("Dances")
    .where("songName", "array-contains", "Title1")
    .get()...

@ Nelson.b.austin चूंकि फायरस्टार के पास अभी तक ऐसा नहीं है, मेरा सुझाव है कि आप एक फ्लैट संरचना है, जिसका अर्थ है:

Dances = {
    danceName: 'Dance name 1',
    songName_Title1: true,
    songName_Title2: true,
    songName_Title3: false
}

इस तरह से होने पर, आप इसे पूरा कर सकते हैं:

var songTitle = 'Title1';
var dances = db.collection("Dances");
var query = dances.where("songName_"+songTitle, "==", true);

आशा है कि ये आपकी मदद करेगा।


2
क्या songName_Title3: falseउपयोगी है? अगर मैं गलत नहीं हूं, तो इसका उपयोग केवल उन नृत्यों की खोज के लिए किया जा सकता है, जिनके पास एक विशिष्ट गाने का नाम नहीं है, यह मानते हुए कि हमें ऐसे परिणाम प्राप्त songName_Title3: falseकरने की आवश्यकता है, dances.where("songName_"+songTitle, "==", false); यह हर नृत्य के लिए हर संभव गीत के लिए बूलियन झंडे लगाने के लिए उपयुक्त नहीं होगा। नाम ...
epeleg

यह महान है लेकिन दस्तावेज़ 1MB तक सीमित हैं, इसलिए यदि आपको तार की एक लंबी सूची या किसी विशिष्ट दस्तावेज़ के साथ जो भी आवश्यक हो, संबद्ध करने की आवश्यकता है, तो आप इस दृष्टिकोण का उपयोग नहीं कर सकते।
सुपरटाइकोनॉफ

@Supertecnoboff ऐसा लगता है कि यह एक बहुत बड़ी और लंबी तार की लंबी सूची होगी। यह प्रदर्शन कैसे "array_contains" क्वेरी है और अधिक प्रदर्शन विकल्प क्या हैं?
जे ऑर्डवे

14

यदि आप संग्रह के रूप में एक वस्तु के रूप में गाने संग्रहित करते हैं तो क्या होगा? प्रत्येक नृत्य एक क्षेत्र के रूप में गाने के साथ: ऑब्जेक्ट टाइप करें (संग्रह नहीं)

{
  danceName: "My Dance",
  songs: {
    "aNameOfASong": true,
    "aNameOfAnotherSong": true,
  }
}

तब आप सभी नामों के लिए क्वेरी कर सकते हैं

db.collection('Dances')
  .where('songs.aNameOfASong', '==', true)
  .get()
  .then(function(querySnapshot) {
    querySnapshot.forEach(function(doc) {
      console.log(doc.id, " => ", doc.data());
    });
   })
   .catch(function(error) {
     console.log("Error getting documents: ", error);
    });

3
यह समाधान काम करेगा लेकिन यह स्केलेबल नहीं है अगर गाने की संख्या बड़ी है या गतिशील रूप से बढ़ सकती है। इससे दस्तावेज़ का आकार बढ़ेगा और पढ़ने / लिखने के प्रदर्शन को प्रभावित करेगा। इस बारे में अधिक Firebase प्रलेखन नीचे लिंक में पाया जा सकता (पिछले अनुभाग 'सीमाओं' पृष्ठ पर देखें) firebase.google.com/docs/firestore/solutions/arrays
Nouman हनीफ

14

अद्यतन 2019

फायरस्टार ने कलेक्शन ग्रुप क्वेरीज़ जारी की हैं। ऊपर गिल का जवाब देखें या आधिकारिक संग्रह समूह क्वेरी दस्तावेज़


पिछला उत्तर

जैसा कि गिल गिलबर्ट ने कहा है, ऐसा लगता है जैसे संग्रह समूह क्वेरीज़ वर्तमान में काम कर रही है। इस समय के दौरान रूट लेवल कलेक्शन का उपयोग करना बेहतर होता है और दस्तावेज़ यूआईडी के उपयोग से इन संग्रह के बीच लिंक होता है।

जो लोग पहले से ही नहीं जानते हैं, उनके लिए जेफ डेलानी के पास एंगुलरफायरबेस पर फायरबेस (और कोणीय) के साथ काम करने वाले कुछ अविश्वसनीय गाइड और संसाधन हैं ।

फायरस्टार NoSQL रिलेशनल डेटा मॉडलिंग - यहाँ वह NoSQL और फायरस्टार DB संरचना की मूल बातें तोड़ता है

उदाहरण के लिए फायरस्टार के साथ उन्नत डेटा मॉडलिंग - ये आपके दिमाग के पीछे रखने के लिए अधिक उन्नत तकनीकें हैं। अपने फायरस्टार कौशल को अगले स्तर तक ले जाने की चाह रखने वालों के लिए एक शानदार रीड


7

नई अद्यतन 8 जुलाई, 2019:

db.collectionGroup('Songs')
  .where('songName', isEqualTo:'X')
  .get()

3

आप हमेशा इस तरह की खोज कर सकते हैं: -

this.key$ = new BehaviorSubject(null);

return this.key$.switchMap(key =>
  this.angFirestore
    .collection("dances").doc("danceName").collections("songs", ref =>
      ref
        .where("songName", "==", X)
    )
    .snapshotChanges()
    .map(actions => {
      if (actions.toString()) {
        return actions.map(a => {
          const data = a.payload.doc.data() as Dance;
          const id = a.payload.doc.id;
          return { id, ...data };
        });
      } else {
        return false;
      }
    })
);

3

क्वेरी की सीमाएँ

क्लाउड फायरस्टोर निम्नलिखित प्रकार के प्रश्नों का समर्थन नहीं करता है:

  1. विभिन्न क्षेत्रों पर रेंज फ़िल्टर के साथ क्वेरी।

  2. कई संग्रह या उपविभाजनों में एकल प्रश्न। प्रत्येक क्वेरी दस्तावेजों के एक संग्रह के खिलाफ चलती है। आपकी डेटा संरचना आपके प्रश्नों को कैसे प्रभावित करती है, इस बारे में अधिक जानकारी के लिए, डेटा संरचना चुनें चुनें

  3. तार्किक या प्रश्न। इस स्थिति में, आपको प्रत्येक OR स्थिति के लिए एक अलग क्वेरी बनानी चाहिए और अपने ऐप में क्वेरी परिणामों को मर्ज करना होगा।

  4. ख! = खंड के साथ प्रश्न। इस स्थिति में, आपको क्वेरी को अधिक-से-अधिक क्वेरी और कम-से-कम क्वेरी से विभाजित करना चाहिए। उदाहरण के लिए, हालांकि क्वेरी क्लॉज जहां ("आयु", "! =", "30") समर्थित नहीं है, आप दो क्वेरी को मिलाकर एक ही परिणाम प्राप्त कर सकते हैं, एक जहां क्लॉज़ है ("आयु", "< "," 30 ") और एक खंड के साथ जहां (" आयु ","> ", 30)।


2
var songs = []    
db.collection('Dances')
      .where('songs.aNameOfASong', '==', true)
      .get()
      .then(function(querySnapshot) {
        var songLength = querySnapshot.size
        var i=0;
        querySnapshot.forEach(function(doc) {
           songs.push(doc.data())
           i ++;
           if(songLength===i){
                console.log(songs
           }
          console.log(doc.id, " => ", doc.data());
        });
       })
       .catch(function(error) {
         console.log("Error getting documents: ", error);
        });

1

एक फ्लैट डेटा संरचना का उपयोग करना बेहतर हो सकता है।
डॉक्स इस पृष्ठ पर विभिन्न डेटा संरचनाओं के पेशेवरों और विपक्षों को निर्दिष्ट करते हैं ।

विशेष रूप से उप-संग्रह के साथ संरचनाओं की सीमाओं के बारे में:

आप आसानी से सबकोलेक्शन को हटा नहीं सकते हैं, या सबकोक्लेक्शन में कंपाउंड क्वेश्चन कर सकते हैं।

एक फ्लैट डेटा संरचना के कथित फायदे के साथ विरोधाभासी:

रूट-स्तरीय संग्रह प्रत्येक लचीलेपन और मापनीयता के साथ-साथ प्रत्येक संग्रह के भीतर शक्तिशाली क्वेरी प्रदान करते हैं।


1

मैंने एक उपाय खोज लिया है। कृपया इसे जाँचे।

var museums = Firestore.instance.collectionGroup('Songs').where('songName', isEqualTo: "X");
        museums.getDocuments().then((querySnapshot) {
            setState(() {
              songCounts= querySnapshot.documents.length.toString();
            });
        });

और फिर आप अपने क्लाउड फायरस्टार में डेटा, रूल्स, इंडेक्स, यूसेज टैब को कंसोल .firebase.google.com से देख सकते हैं। अंत में, आपको इंडेक्स टैब में इंडेक्स सेट करना चाहिए।यहां छवि विवरण दर्ज करें

यहां संग्रह आईडी और कुछ फ़ील्ड मान भरें। फिर संग्रह समूह विकल्प का चयन करें। का आनंद लें। धन्यवाद


इस सवाल का जवाब नहीं है। ऊपर उल्लेखित क्वेरी सिर्फ गीत = 'X' के साथ सभी गीतों को लाती है। यह नाच प्रदान नहीं करेगा जहाँ songName = 'X' है।
साचिन राठौड़

0

मैं यहाँ वेधशालाओं और AngularFire आवरण के साथ काम कर रहा हूँ, लेकिन यहाँ बताया गया है कि मैं ऐसा कैसे कर पाया।

यह पागल की तरह है, मैं अभी भी वेधशालाओं के बारे में सीख रहा हूं और मैं संभवतः इसे पूरा कर रहा हूं। लेकिन यह एक अच्छा व्यायाम था।

कुछ स्पष्टीकरण (आरएक्सजेएस विशेषज्ञ नहीं):

  • songId $ एक अवलोकनीय है जो आईडी का उत्सर्जन करेगा
  • डांस $ एक अवलोकन योग्य है जो उस आईडी को पढ़ता है और फिर केवल पहला मूल्य प्राप्त करता है।
  • तब यह सभी गानों के संग्रह समूह पर सवाल उठाता है ताकि इसके सभी उदाहरण मिल सकें।
  • उदाहरणों के आधार पर यह मूल नृत्य के बारे में पता लगाता है और उनकी आईडी प्राप्त करता है।
  • अब जब हमारे पास सभी डांस आईडी हैं, तो हमें उनका डेटा प्राप्त करने के लिए उन्हें क्वेरी करने की आवश्यकता है। लेकिन मैं यह चाहता था कि मैं एक के बाद एक अच्छे से प्रदर्शन करूं और मैं उन्हें 10 के बकेट में बैच करूं (अधिकतम कोणीय एक inक्वेरी के लिए ले जाएगा ।
  • हम एन बकेट के साथ समाप्त होते हैं और अपने मूल्यों को प्राप्त करने के लिए फायरस्टार पर एन क्वेश्चन करने की आवश्यकता होती है।
  • एक बार जब हम फायरस्टार पर प्रश्न करते हैं, तब भी हमें वास्तव में उस डेटा को पार्स करने की आवश्यकता होती है।
  • और अंत में हम इसमें सभी नृत्यों के साथ एक एकल सरणी प्राप्त करने के लिए सभी क्वेरी परिणामों को मर्ज कर सकते हैं।
type Song = {id: string, name: string};
type Dance = {id: string, name: string, songs: Song[]};

const songId$: Observable<Song> = new Observable();
const dance$ = songId$.pipe(
  take(1), // Only take 1 song name
  switchMap( v =>
    // Query across collectionGroup to get all instances.
    this.db.collectionGroup('songs', ref =>
      ref.where('id', '==', v.id)).get()
  ),
  switchMap( v => {
    // map the Song to the parent Dance, return the Dance ids
    const obs: string[] = [];
    v.docs.forEach(docRef => {
      // We invoke parent twice to go from doc->collection->doc
      obs.push(docRef.ref.parent.parent.id);
    });
    // Because we return an array here this one emit becomes N
    return obs;
  }),
  // Firebase IN support up to 10 values so we partition the data to query the Dances
  bufferCount(10),
  mergeMap( v => { // query every partition in parallel
    return this.db.collection('dances', ref => {
      return ref.where( firebase.firestore.FieldPath.documentId(), 'in', v);
    }).get();
  }),
  switchMap( v => {
    // Almost there now just need to extract the data from the QuerySnapshots
    const obs: Dance[] = [];
    v.docs.forEach(docRef => {
      obs.push({
        ...docRef.data(),
        id: docRef.id
      } as Dance);
    });
    return of(obs);
  }),
  // And finally we reduce the docs fetched into a single array.
  reduce((acc, value) => acc.concat(value), []),
);
const parentDances = await dance$.toPromise();

मैंने अपने कोड को कॉपी किया और चर नामों को बदलकर आपके पास रख दिया, निश्चित नहीं कि कोई त्रुटि है या नहीं, लेकिन इसने मेरे लिए ठीक काम किया। अगर आपको कोई त्रुटि मिलती है तो मुझे बताएं या शायद कुछ नकली फायरस्टार के साथ इसका परीक्षण करने का बेहतर तरीका सुझा सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.