0

enter image description here

Hey MongoDB experts

I am trying to achieve some query results using MongoDB various location features ($near, $geoNear and more).

I have this mongoose model with geoJSON type.

const geoSchema = new Schema({
   type: {
     type: String,
     default: 'Point',
   },
   coordinates: {
     type: [Number],
   },
});

const pickupSchema = new Schema({
  geo_location_from: geoSchema,
  geo_location_to: geoSchema,
});

pickupSchema.index({ geo_location_from: '2dsphere' });
pickupSchema.index({ geo_location_to: '2dsphere' });

What I am trying to achieve is near by location of the event.

I have main pickup event from A to B, and as displayed in the image I have Latitude and Longitude of the all location. Now I am trying to query all of those events object from the db where event geo_location_from is near by Location A (example: A1, A2, A3 ) and geo_location_to is near by Location B ( B1, B2 ).

Here is something I did, which is not right. I am not 100% sure.

Pickup.find(
    {
      $and: [{
        geo_location_from: {
          $near: {
            $maxDistance: 1000,
            $geometry: {
              type: 'Point',
              coordinates: [args.longitude_from, args.latitude_from],
            },
          },
        },
      }, {
        geo_location_to: {
          $near: {
            $maxDistance: 1000,
            $geometry: {
              type: 'Point',
              coordinates: [args.longitude_to, args.latitude_to],
            },
          },
        },
      }],
    },
  )

Some of my try ended up giving various kind of errors. like Too many geoNear expressions and many more.

Anybody has any good solution to this kind of problem ?

Felipe Augusto
  • 7,733
  • 10
  • 39
  • 73
Rutul Patel
  • 663
  • 2
  • 10
  • 23
  • See this https://stackoverflow.com/q/56555547/10273354 – philoez98 Jun 17 '19 at 09:00
  • @philoez98 Thanks for replying. I saw the related post, but in my case I have 2 different locations (from , to ) and I want to find all other location which are happening nearby both of those locartions. – Rutul Patel Jun 17 '19 at 12:40
  • You can try to divide them into different queries: the first gets the nearest places to A, the second the nearest to B. You can then aggregate them and order the result by proximity to one of the locations. – philoez98 Jun 17 '19 at 16:12
  • @philoez98 Thanks for your wonderful and quick reply. Can you please explain more, how can I aggregate them and order the result by proximity to one of the locations ? – Rutul Patel Jun 17 '19 at 16:51
  • See the answer below for more. – philoez98 Jun 17 '19 at 18:03

1 Answers1

1

So I've been thinking of a clever way of doing all you are asking, but I think that it's very hard (if not impossible) to do that only with MongoDb. A perfect solution would be IMHO to use turf.js alongside MongoDb.
I've come up with an approach I think might be what you are looking for.

To get all the places that are at the same time near to both two points in space, we need to define a polygon (an area) where to look for this places. Given that most of the time you have only 2 points, the polygon must be similar to a circle.

There's no way to do this with GeoJson, so turf.js comes in. You can do something like:

// create the points
let point1 =  turf.point([-90.548630, 14.616599]);
let point2 = turf.point([-88.548630, 14.616599])

// we get the midpoint that we'll use as the center of our circle
const midPoint = turf.midpoint(point1, point2) 

// we create a polygon that we'll use as our area
const options = {steps: 100, units: 'kilometers'}; // options for the circle
const circle = turf.circle(midPoint, options)

// a possible place near both locations
let point3 = turf.point([-91.43897, 14.56784])

// then you can get if a point is inside the circle or not
const inside = turf.booleanWithin(point3, circle) 

This is just an idea. You can customize the radius of your circle to get further or nearer places. Then you can of course order the places you've found inside the circle by proximity to the center (this can be done easily in MongoDb).

I'll suggest you to look closely at the turf.js and MongoDb docs to have a clearer idea on how to make them work together seamlessly (and maybe to find a better, easier solution than mine).

philoez98
  • 493
  • 4
  • 13