MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

lấy tài liệu bằng $ box với mongodb và thêm trường khoảng cách cho mỗi bản ghi với điểm tọa độ cụ thể

Cái này sẽ hoạt động:

db.collection.aggregate([
   {
      "$match": {
         "location": {
            "$geoWithin": {
               "$box": [
                  [0.024719919885622943, 51.54643953472475],
                  [-0.1589577534542408, 51.47239969138267]
               ]
            }
         }
      }
   },
   { $set: { lon: -0.0649729793707321 } },
   { $set: { lat: 51.50160291888072 } },
   {
      $set: {
         distance: {
            $let: {
               vars: {
                  dlon: { $degreesToRadians: { $subtract: [{ $arrayElemAt: ["$location.coordinates", 0] }, "$lon"] } },
                  dlat: { $degreesToRadians: { $subtract: [{ $arrayElemAt: ["$location.coordinates", 1] }, "$lat"] } },
                  lat1: { $degreesToRadians: { $arrayElemAt: ["$location.coordinates", 1] } },
                  lat2: { $degreesToRadians: "$lat" }
               },
               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" } }]
         }
      }
   },
])

Chỉ cần lưu ý, $box chỉ được sử dụng cho Các cặp tọa độ cũ . Để có truy vấn thích hợp (tức là sử dụng đúng 2dsphere index) bạn nên sử dụng $geometry :

db.collection.createIndex({ location: "2dsphere" })
db.collection.find(
   {
      "location": {
         "$geoWithin": {
            "$geometry": {
               type: "Polygon",
               coordinates: [[
                  [-0.1589577534542408, 51.47239969138267],
                  [-0.1589577534542408, 51.54643953472475],
                  [0.024719919885622943, 51.54643953472475],
                  [0.024719919885622943, 51.47239969138267],
                  [-0.1589577534542408, 51.47239969138267]
               ]]
            }
         }
      }
   }
).explain().queryPlanner.winningPlan.inputStage.indexName

--> location_2dsphere // which means index is used


db.collection.find(
   {
      "location": {
         "$geoWithin": {
            "$box": [
               [0.024719919885622943, 51.54643953472475],
               [-0.1589577534542408, 51.47239969138267]
            ]
         }
      }
   }
).explain().queryPlanner.winningPlan.stage

--> COLLSCAN // which means full collection scan

Hoặc sử dụng đúng các Tọa độ Kế thừa:

db.collection.createIndex({ "location.coordinates": "2d" })
db.collection.find(
   {
      "location.coordinates": { // <- note this difference
         "$geoWithin": {
            "$box": [
               [0.024719919885622943, 51.54643953472475],
               [-0.1589577534542408, 51.47239969138267]
            ]
         }
      }
   }
).explain().queryPlanner.winningPlan.inputStage.indexName

--> location.coordinates_2d



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. làm thế nào để chuyển một biến cho một regex

  2. Trình điều khiển MongoDB C #, truy vấn bởi một phần tử mảng sử dụng regex

  3. Làm cách nào để lấy tên từ id trong mongoose?

  4. Cách sử dụng mô hình hóa dữ liệu MongoDB để cải thiện hoạt động thông lượng

  5. Sao chép một bộ sưu tập trong MongoDB