在大量数据上使用Mongo Geospatial查询

时间:2019-05-08 10:56:25

标签: mongodb performance mongoose location geospatial

我正在将Mongoose数据库用于打字稿服务器框架Nest中使用Mongoose数据库。

我有2个mongo集合,其中一个包含20,000个用户位置。另一个集合包含从Google Places API收集的10,000个兴趣点。

我现在想找到收集的位置和这些位置(包含经纬度和经纬度的GeoJSON点)之间的交点。

换句话说,我正在寻找与这些POI用户相关的地方。

当前,我有一个异步方法,该方法将使用nearSphere运算符查找某个点附近的所有位置。

然后,我认为下一步将是遍历mongo集合中的每个位置(其中10,000个),然后在每个位置上运行此方法。这样,我将获得一个列表,其中列出了在捕获特定位置时“附近”的POI。

有更好的方法吗?关于性能,我相信这种方式会遇到困难。我找不到mongo地理空间查询,该查询可以让我将两组位置进行比较。

  • 获取所有靠近点的位置
async findAllNearPlace(coords): Promise<Location[]> {
    return await this.locationModel.find(
      {
        location:
          { $nearSphere:
              {
                $geometry: { type: "Point",  coordinates: coords },
                $minDistance: 0,
                $maxDistance: 100
              }
          }
      }
    );
  }

每个POI-检查位置:

async findUsersInProximity(places): Promise<Location[]> {
    const locations = [];
    let i = places.length - 1;
    while (i > 0) {
      await this.findAllNearPlace(
        places[i].location.coordinates
      ).then(intersectingLocations => {
        locations.push(...intersectingLocations);
        i--;
      });
    }
    return await locations;
  }

正如预期的那样,它的性能很差,需要几分钟。

1 个答案:

答案 0 :(得分:0)

您可能可以做的是通过查找创建一个聚合函数,但我并未对其进行测试,并且不确定是否可以提供更好的性能,但是您可以执行类似以下操作:

let pipeline = [
        {
            $geoNear: {
                includeLocs: "location",
                distanceField: "distance",
                near: { type: 'Point', coordinates: "$$point" },
                maxDistance: 20,
                spherical: true
            }
        }
    ];

UsersModel.aggregate([{
   $lookup : {
     from : 'locations',
     let : {point : '$address'}, //whatever the field for the coordinates is 
     pipeline ,
     as : 'places'   
   }
}])