2013-06-26 16 views
5

Ponieważ baza ogniowa nie obsługuje indeksowania przestrzennego, używam geohash, które ktoś tutaj zaleca. Geohash używa znaków, aby znaleźć w pobliżu.Jak wyszukiwać w Firebase klucze odpowiadające prefiksowi ciągów znaków

Więc powiedzmy mam w22qt4vhye1cw99qt4vdf4vcw22qt4vhzerct geohash sklep w Firebase i chcę tylko zapytać, która geohash blisko w22qt4.

Jak to zrobić?

Wiem, że firebase ma startAt. Próbowałem, ale nie działałem.

UPDATE

Przechowywanie geohash do Firebase

//Encode lat lng, result w22qt4vhye1c3 
var geoHashLatLng = encodeGeoHash(lat,lng); 
firebaseRef.child('/geohash/' + geoHashLatLng).set(id); 

więc w json

root 
    - geohash 
     - w22qt4vhye1c3 
     - id 
     - z99qt4vdf4vc 
     - w22qt4vhzerct 

Moje pytanie tutaj. Po prostu chcę zapytać geohash, które zaczynają się od znaków w22qt4. Czy możemy to zrobić w bazie ogniowej?

UPDATE 2 startAt() wydaje się nie ze znaków zapytania zacząć ...

Przykład: Mam następujący gehash

geohash węzła

geohash 
    - a123 
    - a333 
    - b123 
    - c123 
    - d123 

z następującego kodu

var firebaseRef = new Firebase('https://test.firebaseio.com'); 
var query = firebaseRef.child('/geohash').startAt(null, 'a'); 
query.on('child_added', function(snapshot) { 
    console.log(snapshot.name()); 
}); 

dostanie skutkuje

startAt(null, 'a') //return a123, a333, b123, c123, d123 
startAt(null, 'c123') //return c123, d123 
startAt(null, 'd') //return d123 

Moje oczekiwanych rezultatów

startAt(null, 'a') //return a123, a333 
startAt(null, 'c123') //return c123 
startAt(null, 'd') //return d123 

Zgaduję, startAt() będzie kwerendy 26 litery alfabetu w kolejności, ale nie pasujące. Co mogę zrobić w firebase, aby uzyskać powyżej oczekiwane wyniki?

+0

Czy możesz podać fragment kodu, który próbujesz, aby zapewnić bardziej znaczącą informację zwrotną? –

+0

@AndrewLee Cześć, właśnie zaktualizowałem moje pytanie, proszę spojrzeć. – vzhen

+0

Możesz użyć "endAt", aby zakończyć na konkretnym klawiszu. Zobacz zmiany w moim wpisie poniżej. –

Odpowiedz

5

Oprócz odpowiedzi powyżej Andrzeja, co chcesz zrobić, aby uzyskać pożądany efekt z geohashes (czyli być w stanie wykonać kwerendy prefiksu, które pozwalają określić dokładność w „zapytania”, a konkretnie, na przykład co 3 znaki w geohashie dostaniesz ~ + -80 km) to przechowywanie danych w bardziej ziarnistej i dyskretnej formie.

Tak więc, zamiast zapisywać go teraz, będziesz chciał zapisać dane przez pocięcie klucza łańcucha geohash na fragmenty (zrobiłem to na granicy 3 znaków, ale powinieneś wybrać odpowiedni strategia tokenizacja który daje żądaną dokładność) i wykorzystać każdy fragment jako imię dziecka, jako takich:

root 
    - geohash 
     - w22 
     - qt4 
      - vhy 
      - e1c 
       - w22qt4vhye1c3 
       - id 
      - vhz 
      - erc 
       - w22qt4vhzerct 
       - id 
     - z99 
      - qt4 
      - vdf 
       - z99qt4vdf4vc 
       - id 

Potem, jak w swoim pytaniu, gdy trzeba uzyskać wszystkie geohashes które zaczynają w22qt4 byś zrobić zapytanie dotyczące:

firebaseRef.child('/geohash/w22/qt4/') 

Które następnie dałoby dzieciom vhy i vhz, które będą miały wszystkie rzeczywiste geohasy, którymi jesteś zainteresowany.

+0

Jak zapytać, gdzie jest wartość val poniżej pod-dziecko? Czytam do dokumentów firebase. Znalazłem 'hasChildren()' i 'forEach()'. Czy to właściwe rzeczy do wykorzystania? A propos, czy mogę użyć w angularFire? ponieważ używam firebase z angularjs. – vzhen

+0

Ponieważ dane zostały zdenormalizowane w określony sposób, nie trzeba stosować kwerend Firebase. Możesz dołączyć słuchaczy do odpowiedniego poziomu w drzewie i spowoduje zwrócenie wszystkich podrzędnych w zwalnianych migawkach. – Vikrum

2

Możesz użyć zwykłego zapytania startAt, aby znaleźć klucze w pobliżu określonego klucza. Na przykład w tym przypadku:

var query = firebaseRef.child("geohash").startAt(null, 'c').limit(5); 
query.on("child_added", ...); 

Daje to 5 elementów po geoHashLatLng po posortowaniu leksykograficznym.

Jeśli chcesz zakończyć zapytanie pod określonym kluczem, możesz to zrobić. Na przykład:

var query = firebaseRef.child("geohash").startAt(null, 'c').endAt('d'); 
+0

Nie otrzymuję tego, czego chcę, zaktualizowałem ponownie moje pytanie. Myślę, że tym razem jest jaśniej. Proszę sprawdź to. Dzięki – vzhen

+0

Przepraszam, zapomniałem wspomnieć, że nie wiem, co to jest koniec. Dodałem skrzypce. Proszę spojrzeć na http://plnkr.co/edit/Wtkq4978r1a4dnSLl9qi?p=preview – vzhen

+0

Nie mamy sposobu, aby po prostu zapytać przez prefiks. Musisz dowiedzieć się, gdzie powinno się kończyć zapytanie. Zamawiamy rzeczy leksykograficznie, więc jeśli chcesz c *, możesz zacząć od początku i końca, a następnie wyrzucić dokładnie to samo co d. –

Powiązane problemy