MichaelSolati / geofirestore-js

Location-based querying and filtering using Firebase Firestore.
https://geofirestore.com
MIT License
505 stars 58 forks source link

Question - how can I find near documents with each unique radius? #205

Closed Newbie012 closed 3 years ago

Newbie012 commented 3 years ago

I have a collection of exposures. Each exposure has:

coordinates: GeoPoint;
radius: number; // km

Meaning, each exposure has its own coordinate and radius. This is, in fact, the opposite case of how the query in the docs works:

const query = geocollection.near({ center: new firebase.firestore.GeoPoint(40.7589, -73.9851), radius: 1000 });

If I'm not mistaken, This query will find all of the documents near the given point with a radius of 1000. But how can I (if it's possible) run a query with just a point that will return all of the exposures within the radius based on their own .radius?

I assume I'll have to create an additional property to calculate that, but I'm not sure how exactly. Help would be highly appreciated :)

MichaelSolati commented 3 years ago

Did you create your documents with the geofirestore library? They need to have a specific data structure in order to work see here.

Newbie012 commented 3 years ago

I haven't yet implement geofirestore into my app. I wanted to first check if my goal is possible. According to the data structure you mentioned, there's a geohash so I assume what I'm trying to achieve is possible. But I guess the geohash is autogenerated by the library. So I guess my question now is of there's a way for me to pass a radius to the add method.

MichaelSolati commented 3 years ago

Ok, so you'd need to run two queries. The first would be something like const exposure = (await geocollection.doc('docid'),get()).data() get the radius and coordinates and then pass that into the const query = geocollection.near({ center:exposure.coordinates, radius: exposure.radius });

As far as you adding the radius to the add method, yes, you just add a document with whatever fields you want into the add method. The only requirement for a doc is that it has a field called coordinates which is a GeoPoint.

Newbie012 commented 3 years ago

@MichaelSolati The tricky part is that I don't have a document id. I need to run the query on a collection with possibly thousands of documents.

MichaelSolati commented 3 years ago

So you want to query a doc based on location and then use that doc to query more docs? Unfortunately this would need to be a 2 step process, though you could use limit and use a small radius to limit the amount of data you get back when trying to find the doc that is your origin.

Newbie012 commented 3 years ago

Not exactly. I have documents that already have coordinates, but they have a radius as well. Meaning, instead of me, sending the radius, I only send my current coordinates and I want to get all of the other documents that given their coordinates with their radius will intersect my coordinate.

For example, I have 2 documents:

{
  g: [12.3456, 54.3211]
  radius: 100
},
{
  g: [76.543, 34.567]
  radius: 50
}

Given the geopoint [12.346, 54.322], I want to get the first document, since its radius is within the range of my geopoint.

MichaelSolati commented 3 years ago

I believe you could use a radius query of 0, which would match the exact document. Or you could (I don't know if this works query the doc with something like geocollection.where('coordinates', '==', theGeoPoint)).

Newbie012 commented 3 years ago

@MichaelSolati but they're not the same point. And maybe my example is not good enough, but the idea is that each document has it own radius. So instead of me passing a radius and a coordinates, I will send just the coordinates and I'll get all of the documents that are in proximity based on their own radius

MichaelSolati commented 3 years ago

It'll still have to be 2 queries. You'd have to do one with coordinates of the document who's radius you want (that query you'll do with a radius of 0). And the. Once you have that doc you'll make a query with the radius set in the doc.

Newbie012 commented 3 years ago

But the documents with their own radius has their own coordinates as well, so if I queried then once, then I won't need to query them again. But the problem is that if my collection scales to 1m documents, then I'll have to do 1m reads. Which leads to my next assumption that if I'm already about to fetch all of the documents, then I don't even need to query the proximity. Am I correct?

MichaelSolati commented 3 years ago

When you make a geoquery the library doesn't read all of the documents, it only reads some based on matching them to ranges of geohashes. Ideally you wouldnt have to read all 1m docs. I don't think I understand what you're trying to do and where the problems are.