使用mongodb查找附近位置的对象|所有附近的位置A到所有附近的位置B

时间:2019-06-16 23:53:24

标签: mongodb mongoose geojson

enter image description here

MongoDB专家

我正在尝试使用MongoDB的各种位置功能($ near,$ geoNear等)来实现一些查询结果。

我有这个带有geoJSON类型的猫鼬模型。

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' });

我要达到的目标是根据事件的位置。

我有一个从A到B的主要接人活动,并且如图所示,我具有所有位置的纬度和经度。现在,我正在尝试从数据库中查询所有这些事件对象,其中事件geo_location_from在位置A附近(例如:A1,A2,A3),而geo_location_to在位置B附近(B1,B2)。

这是我做的事情,这是不对的。我不确定100%。

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],
            },
          },
        },
      }],
    },
  )

我的某些尝试最终导致各种错误。 例如 geoNear表达式过多等。

有人对这种问题有什么好的解决办法吗?

1 个答案:

答案 0 :(得分:1)

因此,我一直在考虑一种聪明的方式来完成您所要解决的所有问题,但是我认为仅使用MongoDb很难做到这一点(如果不是不可能的话)。 完美的解决方案是恕我直言,将turf.js与MongoDb一起使用。
我想出了一种我认为可能是您正在寻找的方法。

要获得同时靠近空间两个点的所有位置,我们需要定义一个多边形(一个区域)以在其中寻找该位置。鉴于大多数情况下您只有2个点,因此多边形必须类似于圆形。

无法使用GeoJson做到这一点,因此出现了 turf.js 。您可以执行以下操作:

// 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) 

这只是一个想法。您可以自定义圆的半径以获得更远或更近的位置。然后,您当然可以按照与中心的接近程度来排序在圆内找到的位置(这可以在MongoDb中轻松完成)。

我建议您仔细查看 turf.js MongoDb 文档,以便更清晰地了解如何使它们无缝地协同工作(也许找到比我更好,更轻松的解决方案。