计算 MongoDB 聚合管道中两个地理坐标之间的距离

问题描述 投票:0回答:1

我有一个 MongoDB 集合,其中包含地理坐标存储为 GeoJSON 对象的文档。每个文档代表一个具有两个位置(location_1 和 location_2)的项目。这是一个示例文档结构:

[
  {
    "_id": ObjectId("62c43a4128c8b27fda436536"),
    "item": "item1",
    "location_1": {
      "type": "Point",
      "coordinates": [76.22191167727965, 10.929396489878417]
    },
    "location_2": {
      "type": "Point",
      "coordinates": [76.2249520851109, 10.97594496161423]
    }
  },
  {
    "_id": ObjectId("62c43a4128c8b27fda436537"),
    "item": "item2",
    "location_1": {
      "type": "Point",
      "coordinates": [50.22191167727965, 10.929396489878417]
    },
    "location_2": {
      "type": "Point",
      "coordinates": [10.2249520851109, 10.97594496161423]
    }
  },
  // Additional documents...
]

我想使用 MongoDB 聚合管道计算每个项目的 location_1 和 location_2 之间的公里距离。

我知道 MongoDB 有一个用于地理空间查询的 $geoNear 聚合阶段,但我不确定如何使用它来计算同一文档中两点之间的距离。

有人可以提供一个如何使用 MongoDB 聚合管道实现此目的的示例吗?

谢谢!

mongodb mongoose nestjs geojson
1个回答
0
投票

我建议使用Haversine公式

db.collection.aggregate([
   {
      $set: {
         distance: {
            $let: {
               vars: {
                  dlon: { $degreesToRadians: { $subtract: [{ $first: "$location_1.coordinates" }, { $first: "$location_2.coordinates" }] } },
                  dlat: { $degreesToRadians: { $subtract: [{ $last: "$location_1.coordinates" }, { $last: "$location_2.coordinates" }] } },
                  lat1: { $degreesToRadians: { $last: "$location_1.coordinates" } },
                  lat2: { $degreesToRadians: { $last: "$location_2.coordinates" } }
               },
               in: {
                  // Haversine formula: sin²(dLat / 2) + sin²(dLon / 2) * cos(lat1) * cos(lat2);
                  $add: [
                     { $pow: [{ $sin: { $divide: ["$$dlat", 2] } }, 2] },
                     { $multiply: [{ $pow: [{ $sin: { $divide: ["$$dlon", 2] } }, 2] }, { $cos: "$$lat1" }, { $cos: "$$lat2" }] }
                  ]
               }
            }
         }
      }
   },
   {
      $set: {
         distance: {
            // Distance in Meters given by "6372.8 * 1000"
            $multiply: [6372.8, 1000, 2, { $asin: { $sqrt: "$distance" } }]
         }
      }
   }
])

蒙戈游乐场

© www.soinside.com 2019 - 2024. All rights reserved.