Search code examples
geolocationgoogle-cloud-firestoregeofiregeohashinggeofirestore

Ordering Firestore GeoHash query from closest to furthest?


Currently, I'm using parts of the GeoFirebase library along with Firestore to allow for geoquerying. When I set the geohash of a post, I do it as such if let geoHash = GFGeoHash(location: location.coordinate).geoHashValue {

However, to make the geohash querying less specific, I'm planning on truncating part of the geohash when I query; currently, the query looks similar to this

 var geoQuerySpecific = GFGeoHashQuery()
        let geoQueryHash =  GFGeoHashQuery.queries(forLocation: (lastLocation?.coordinate)!, radius: (30)) as! Set<GFGeoHashQuery>

        for query in geoQueryHash {
            geoQuerySpecific = query
            print("the key is this um \(geoQuerySpecific)")
        }
        print("the starting value is \(geoQuerySpecific.startValue)  and the end value is \(geoQuerySpecific.endValue)")
        let nearQuery = Firestore.firestore().collection("stuff").order(by: "g").whereField("g", isGreaterThanOrEqualTo: geoQuerySpecific.startValue).whereField("g", isLessThanOrEqualTo: geoQuerySpecific.endValue)

As you can see, this won't work correctly as there are multiple items in the geoQueryHash. I've thought about truncating the last four digits/letters from the geohash when I am setting it in firebase, however, that won't be specific enough. To get the closest posts, would it be best to set the geoHashes in the database as I currently am, then, when retrieving the stuff, make the start value the most specific geohash for the query and then make the end value the truncated version of the geohash, as to start by getting the closest posts and end with the broadest?

I can limit the Firestore query to 50, so then I can retrieve the 50 posts from closest to furthest... is my understand of geo hashing correct? Would this be feasible?

Conceputally, if there were a way to store geohashes as integers than I could make the firestore query start at the largest integer (i.e. most precise Geohash) and then work order the query by descending until it gets to the least precise intenser (broadest geoHash) and then limit it to 50.


Solution

  • GeoFirestore uses geohashes to be able to select documents that are within a range of geohashes, which is roughly the same as an area on the map. There is no way to retrieve those documents within a specified order from within that area with just a geoquery. If you want to have the documents sorted by distance, you will have to do that after the geoquery, in your application code.

    If you want to learn more on why that is, have a look at a talk I gave a while ago: Querying Firebase and Firestore based on geographic location or distance. In it I explain how geohashes work, how they allow you to select documents in a certain geographic range, and why you can't do the more complex query on Firestore (or Firebase's original realtime database).