How to do complex queries with geofire?

2,407 views
Skip to first unread message

Robin Linus

unread,
Mar 7, 2016, 5:40:27 PM3/7/16
to Firebase Google Group
I am trying to use GeoFire, but even after reading all the examples here https://github.com/firebase/geofire-js/tree/master/examples I don't quite understand how it works. 
with this snipped you can set a geo location for a single key:  
```
geoFire.set("some_key", [37.785326, -122.405696]).then(function() {
  console.log("Provided key has been added to GeoFire");
}, function(error) {
  console.log("Error: " + error);
});
```
but how do I use geo locations for complex objects instead of simple string keys? 
what if you have a restaurant with a name, average dish price and opening hours? do you need to store them in a second collection and somehow join them in your query?
I found this discussion https://github.com/firebase/geofire-js/issues/40 — it answers the question that you actually need to keep the geofire data in a seperate collection, but i am still wondering: 
how do you make more complex queries such as "near my location, open now and $15 avg dish price" ? do you really need to load all ids of locations nearby and then send those ids back to the server in a second query to filter out the ones that match the complex query? how do you do that? is there any example?

thanks a lot for your help!

Jacob Wenger

unread,
Mar 7, 2016, 7:08:25 PM3/7/16
to fireba...@googlegroups.com
This is a duplicate of https://github.com/firebase/geofire-js/issues/95. I'm going to close the GitHub issue since this is probably a better forum for this kind of question.

By the way, I saw your question on GitHub when you posted it. We get a ton of support and it's not practical to have a two hour turnaround on all GitHub issues. In the future, please be patient and avoid double posting as that just makes more effort for everyone involved. Thanks.

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To post to this group, send email to fireba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/6fd9058d-29a6-4539-b111-494b27454d16%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jacob Wenger

unread,
Mar 8, 2016, 1:42:17 PM3/8/16
to Jacob Wenger, fireba...@googlegroups.com
Hey Robin,

Unfortunately, Firebase Queries currently only allow you to query on a single child, meaning you can't do queries on multiple variables like location, price, rating, etc. The one variable GeoFire uses is location. That doesn't mean you can't use GeoFire to do what you want, although it will require doing some client-side filtering. This unfortunately means you will be pulling down more data than you actually use, but depending on how much data you have, this may not be a huge performance problem.

You have two options:
  • Use GeoFire to get all relevant restaurants within a certain location radius and then use client-side code to filter all the returned results:

    var rootRef = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
    var geoFireRef = rootRef.child("_geofire");
    var restaurantsRef = rootRef.child("restaurants");

    var geoFire = new GeoFire(geoFireRef);

    var geoQuery = geoFire.query({
      center: [10.38, 2.41],
      radius: 10.5
    });

    var matches = [];

    // Listen to every restaurant in our query...
    geoQuery.on("key_entered", function(key) {
      // ... and look them up by key ...
      restaurantsRef.child(key).once("value", function(snapshot) {
        var restaurant = snapshot.val();
        // .. and filter out any restaurants with expensive dishes
        if (restaurant.averageDishPrice <= 15) {
          matches.push(restaurant);
        }
      });
    });


  • Create multiple GeoFire indexes (e.g one for dishes with prices  < $10, one for dishes with prices $10 - $15, one for dishes with prices > $20) and then just query the GeoFire index you want. I don't think this is a very good option though since you don't want to end up creating a ton of GeoFire indexes and it also means your filtering will be limited to what GeoFire indexes you have created. This won't scale well.
I'd go with the first option. Hopefully in the future Firebase will have support for queries on multiple children at once which will make this sort of thing much easier. Until then, you're going to have to do some client-side filtering to get this behavior.

Cheers,
Jacob
Reply all
Reply to author
Forward
0 new messages