8

Since firebase not support any spatial indexing then I use geohash which someone advice here. Geohash is using characters to find the nearby.

So let say I have w22qt4vhye1c w99qt4vdf4vc w22qt4vhzerct geohash store in firebase and I want to query only which geohash close to w22qt4.

How to do that?

I know firebase has startAt. I tried but not work.

UPDATE

Storing geohash to firebase

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

so in json

  root
   - geohash
      - w22qt4vhye1c3
         - id
      - z99qt4vdf4vc
      - w22qt4vhzerct

My question here. I Just want to query geohash which start from characters w22qt4. Can we do that in firebase?

UPDATE 2 startAt() seems like not query with characters start with ...

Example: I have following gehash

geohash node

geohash
  - a123
  - a333
  - b123
  - c123
  - d123

With the following code

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());
});

Will get this results

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

My expected results

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

My guess, startAt() will query the 26 alphabet letters in sequence but not matching. So, what can I do in firebase so I can get my expected results above?

4

2 回答 2

7

In addition to Andrew's answer above, what you want to do to get the desired effect with geohashes (i.e. be able to do prefix queries that let you specify accuracy in the 'query', specifically, for example every 3 characters in the geohash gets you ~ +-80km) is to store the data in a more granular and discretized manner.

So, rather than how you're storing it now, you'll want to save the data by chopping the geohash string key into fragments (I've done it at the 3 character boundary, but you should choose an appropriate tokenization strategy that gives you the desired accuracy) and use each fragment as a child name, as such:

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

Then, as in your question, when you need to get all geohashes that start with w22qt4 you would do a query against:

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

Which would then give you the vhy and vhz children which then have all the actual geohashes that you were interested in.

于 2013-07-09T00:31:31.957 回答
2

您可以使用普通的 startAt 查询来查找指定键附近的键。例如,在这种情况下,您将:

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

当按字典顺序排序时,这将为您提供 geoHashLatLng 之后的 5 个元素。

如果您想在某个指定的键处结束查询,您也可以这样做。例如:

var query = firebaseRef.child("geohash").startAt(null, 'c').endAt('d');
于 2013-06-29T19:20:07.480 回答