Do czego służy typ danych „Odniesienie” Firebase Firestore?

189

Właśnie eksploruję nowy Firebase Firestore, który zawiera typ danych o nazwie reference. Nie jest dla mnie jasne, co to robi.

  • Czy to jest jak klucz obcy?
  • Czy można go użyć do wskazania kolekcji, która znajduje się gdzie indziej?
  • Jeśli referencejest to rzeczywiste odniesienie, czy mogę go używać do zapytań? Na przykład, czy mogę mieć odniesienie, które wskazuje bezpośrednio na użytkownika, zamiast przechowywać ID użytkownika w polu tekstowym? I czy mogę użyć tego odniesienia do zapytań?
Jürgen Brandstetter
źródło
18
Myślę, że ten film od zespołu Firebase rozkłada go dla ciebie: youtube.com/watch?v=Elg2zDVIcLo (oglądaj z 4:36)
Adarsh

Odpowiedzi:

91

Referencje są bardzo podobne do kluczy obcych.

Aktualnie wydane zestawy SDK nie mogą przechowywać odniesień do innych projektów. W ramach projektu odniesienia mogą wskazywać na dowolny inny dokument w dowolnej innej kolekcji.

Możesz używać referencji w zapytaniach, jak każdej innej wartości: do filtrowania, porządkowania i stronicowania (startAt / startAfter).

W przeciwieństwie do kluczy obcych w bazie danych SQL odwołania nie są przydatne do wykonywania połączeń w jednym zapytaniu. Możesz ich użyć do wyszukiwania zależnych (które wyglądają jak łączenie), ale bądź ostrożny, ponieważ każdy skok spowoduje kolejną podróż w obie strony na serwer.

Gil Gilbert
źródło
9
Czy możesz podzielić się możliwymi przypadkami użycia? Czy możliwe jest zapytanie o pola w tym odwołaniu? Np. Mam friendskolekcję z listą wszystkich moich znajomych ( friends/myId). Następnie odsyłam do tego dokumentu w friendspolu innego dokumentu ( group/groupId). Chciałbym, aby wyświetlić tylko moich przyjaciół, którzy są w tej grupie, robiąc coś takiego: where('friends.myId', '==', true).
Czy
108
Przy okazji, przydatne może być zaktualizowanie dokumentów, aby zawierały przykład dodawania typu odwołania.
Czy
11
Nie mogę znaleźć żadnych informacji na ten temat? Spowoduje to zmianę całej mojej struktury bazy danych, muszę wiedzieć więcej ...
Ruben
3
czy masz przykład (najlepiej w trybie szybkim), w jaki sposób zapytać za pomocą odwołania? w tej chwili mogę to zrobić, przechowując nieprzetworzony identyfikator użytkownika jako ciąg, ale to nie wydaje się właściwe.
Mickey Cheong,
6
Potrzebuję zmienić wszystkie moje typy referencji na ciągi, ponieważ zapytanie zawsze zawiedzie z typem referencji. Dosłownie nie mogę znaleźć niczego o tym, jak zapytać według typu referencji :( jeśli ktoś dowie się, jak zapytać według typu referencji, daj mi znać ...
Sam Trent
133

Dodanie poniżej tego, co działało dla mnie przy użyciu referencji w Firestore.

Jak mówią inne odpowiedzi, to jest jak klucz obcy. Atrybut referencyjny nie zwraca jednak danych dokumentu referencyjnego. Na przykład mam listę produktów z referencją userRef jako jednym z atrybutów produktu. Uzyskiwanie listy produktów daje mi odniesienie do użytkownika, który utworzył ten produkt. Ale nie podaje mi szczegółów użytkownika w tym odnośniku. Użyłem innego zaplecza jako usługi ze wskaźnikami, które wcześniej miały flagę „wypełnij: prawda”, która zwraca dane użytkownika zamiast tylko identyfikatora referencyjnego użytkownika, co byłoby fajne, aby mieć tutaj (mam nadzieję, że przyszłe ulepszenie ).

Poniżej znajduje się przykładowy kod, którego użyłem, aby ustawić referencję, a także uzyskać listę produktów, a następnie uzyskać dane użytkownika z podanego identyfikatora referencji użytkownika.

Ustaw referencję w kolekcji:

let data = {
  name: 'productName',
  size: 'medium',
  userRef: db.doc('users/' + firebase.auth().currentUser.uid)
};
db.collection('products').add(data);

Uzyskaj kolekcję (produkty) i wszystkie odniesienia do każdego dokumentu (dane użytkownika):

db.collection('products').get()
    .then(res => {
      vm.mainListItems = [];
      res.forEach(doc => {
        let newItem = doc.data();
        newItem.id = doc.id;
        if (newItem.userRef) {
          newItem.userRef.get()
          .then(res => { 
            newItem.userData = res.data() 
            vm.mainListItems.push(newItem);
          })
          .catch(err => console.error(err));
        } else {
          vm.mainListItems.push(newItem);  
        }

      });
    })
    .catch(err => { console.error(err) });

Mam nadzieję że to pomoże

Ben Cochrane
źródło
3
Dzięki za udostępnienie! Myślę, że w pierwszym wierszu Get part jest literówka i tak powinno być db.collection('products').get(). Czy próbowałeś bezpośrednio uzyskać użytkownika? Domyślam się, że newItem.userRef.get()powinien działać zamiastdb.collection("users").doc(newItem.userRef.id).get()
Siergiej Nefedyjew
53
Przede wszystkim dziękuję za przykład. Mam nadzieję, że dodadzą w przyszłości „zaludnienie: prawda”. W przeciwnym razie zapisanie odwołania jest nieco bezcelowe. To samo można zrobić, po prostu zapisując uidi referencje za jego pośrednictwem.
Jürgen Brandstetter,
4
Dzięki za przykład! Ale jaki jest sens przechowywania typu odwołania, jeśli nie ma opcji „zapełniania” podczas zapytania do dokumentu? Jeśli istnieje opcja wypełnienia, o której ktokolwiek wie, daj mi znać.
Harshil Shah
18
W rzeczywistości nie jest to klucz obcy. Dla mnie to w zasadzie nic nie ma - jaki jest sens, referencejeśli nie możemy go użyć, ponieważ prawdziwy klucz obcy powinien działać?
jean d'arme
14
Tak więc jedyną zaletą referencenad a stringjest to, że możesz wywołać get()odwołanie bezpośrednio. Jeszcze niezbyt przydatne. Mam nadzieję, że dodają opcję automatycznego zapełniania odniesień odpowiednimi obiektami!
morgler,
16

Dla tych, którzy szukają rozwiązania JavaScript do wysyłania zapytań przez referencję - chodzi o to, że w instrukcji zapytania należy użyć obiektu „odwołanie do dokumentu”

teamDbRef = db.collection('teams').doc('CnbasS9cZQ2SfvGY2r3b'); /* CnbasS9cZQ2SfvGY2r3b being the collection ID */
//
//
db.collection("squad").where('team', '==', teamDbRef).get().then((querySnapshot) => {
  //
}).catch(function(error) {
  //
});

(Uznanie dla odpowiedzi tutaj: https://stackoverflow.com/a/53141199/1487867 )

Aswin Kumar
źródło