问题
I want to query users which I have stored in a collection named "Users". Each user has fields such as age and weight. Is there a way I can query the users by distance from the user running the search with GeoFire and combine it with FireStore search queries? For instance, I am a user who is looking for someone who is in a 20 mile radius but also wants to find someone who is between 2 years younger or older than them.
回答1:
The Firestore database can filter on multiple fields, but it can only do a range filter on one of those fields. So this query is possible:
collection.where("age", ">", 18).where("age", "<", 20)
But this is not possible:
// !!!THIS WON'T WORK!!!
collection.where("latitude", ">", 18.001).where("longitude", "<", 21.312)
The GeoFirestore libraries that I know of, all use geohashes (as used in the original GeoFire libraries) to be able to do something that is seemingly impossible on the underlying database: filtering documents in a geographic range based on latitude and longitude.
Geohashes work their magic by combining the latitude and longitude of a location into a single string value, that can be filtered with varying degrees of accuracy. This is possible, since you can (sort of) express how one degree of longitude related to a degree of latitude. So you sort of zip-merge the digits of lat and lon into a single value, which has the most significant digit of each first.
Now this also explains why you can't simply add another range filter to the geoquery. You'd have to find a way to express the age difference in terms of distance. If you can do that, it's "just" a matter of encoding the extra information into the geo-age-hash. It sounds quite complex to me, but it is at least possible.
The first problem is though that there is no generic way to relate additional properties to latitude and longitude, which is why you'll be on your own to solve this problem. My gut feeling is that most developers give up on this requirement, or do the additional ordering/filtering client-side.
If you want to add an equality filter to a geohash (e.g. documents for people in a certain geographic range who are exactly 18), that is definitely possible on a Firestore level, although I don't know if the GeoFirestore libraries expose the underlying query capabilities to do that.
I highly recommend learning more on the subject, as it is quite fascinating. Some sources:
- If you want to learn more on why Firestore can only range filter on a single field, watch this video from the Get to know Cloud Firestore series.
- If you want to learn more about geohashes, geoqueries, and how you can implement them on Firestore watch my talk about the topic.
- The wikipedia explanation of geohashes.
I also recommend checking out these previous questions on the topic:
- Filtering results with Geofire + Firebase
- How to do complex queries with geofire?
- Can I use firebase's GeoFire with Priority in a single query?
Many of these are about GeoFire for the (original) Firebase Realtime Database, but the same principles would apply to Firestore.
来源:https://stackoverflow.com/questions/56572432/is-there-a-way-i-can-combine-a-geofirestore-query-with-a-normal-firestore-query