0
0
Lập trình
Hưng Nguyễn Xuân 1
Hưng Nguyễn Xuân 1xuanhungptithcm

Làm Việc Với Dữ Liệu Địa Lý Trong MongoDB

Đăng vào 1 tháng trước

• 7 phút đọc

Hướng Dẫn Làm Việc Với Dữ Liệu Địa Lý Trong MongoDB

MongoDB cung cấp một cách đơn giản để làm việc với dữ liệu địa lý, giúp bạn dễ dàng lưu trữ và truy vấn dữ liệu này. Trong bài viết này, chúng ta sẽ tìm hiểu cách mô hình hóa dữ liệu địa lý, tạo chỉ mục địa lý và thực hiện các truy vấn địa lý.

Mô Hình Hóa Dữ Liệu Với GeoJSON

Cách tốt nhất để lưu trữ và tương tác với dữ liệu địa lý trong MongoDB là sử dụng GeoJSON.

GeoJSON là một định dạng dữ liệu địa lý dựa trên JSON, định nghĩa nhiều loại đối tượng JSON để đại diện cho các đặc điểm địa lý và thuộc tính của chúng.

Đối với mục đích của chúng ta, chúng ta sẽ tập trung vào loại Point. Để lưu trữ một điểm, bạn cần có typecoordinates:

json Copy
{
  "name": "York Minster",
  "category": "history",
  "location": {
    "type": "Point",
    "coordinates": [
      -1.081,
      53.962
    ]
  }
}

Lưu ý: Thứ tự tọa độ quan trọng - nó là [kinh độ, vĩ độ]. Điều này có thể khác với cách một số ứng dụng bản đồ xử lý thứ tự tọa độ.

Trong ví dụ này, chúng ta đã đặt tên cho điểm location và có type cùng một mảng coordinates.

Tạo Chỉ Mục Địa Lý

Để thực hiện các truy vấn trên các vị trí của chúng ta, chúng ta cần tạo một loại chỉ mục đặc biệt gọi là chỉ mục địa lý:

javascript Copy
db.places.createIndex({ location: "2dsphere" });

Điều này sẽ tạo một chỉ mục trên trường vị trí của chúng ta. Tuy nhiên, chúng ta cũng có thể muốn tạo một chỉ mục hỗn hợp bao gồm cả loại của vị trí:

javascript Copy
db.places.createIndex(
  { category: 1, location: "2dsphere" }
);

Bây giờ, chúng ta có thể nhắm đến các truy vấn theo loại vị trí trước, trước khi kiểm tra khoảng cách nếu muốn.

Một chỉ mục loại 2dsphere sẽ hỗ trợ các truy vấn diễn giải hình học trên một hình cầu.

Thực Hiện Các Truy Vấn Địa Lý

Có nhiều truy vấn liên quan đến địa lý mà bạn có thể thực hiện với MongoDB. Chúng ta sẽ chủ yếu tập trung vào $near$geoWithin.

Truy vấn địa lý đơn giản nhất là $near, sẽ trả về các tài liệu có vị trí gần nhất với vị trí đã cung cấp:

javascript Copy
db.places.find({
  location: {
    $near: {
      $geometry: { 
        type: "Point",
        coordinates: [-0.0761, 51.508]
      }, 
      $maxDistance: 2000
    }
  }
});

Điều này sẽ trả về hai vị trí gần London trong vòng 2.000 mét:

json Copy
{
  _id: ObjectId('68b75623ad2321ea365d00e8'),
  name: 'Tower of London',
  category: 'history',
  location: {
    type: 'Point',
    coordinates: [-0.0761, 51.5081]
  }
},
{
  _id: ObjectId('68b75623ad2321ea365d00ec'),
  name: "St. Paul's Cathedral",
  category: 'history',
  location: {
    type: 'Point',
    coordinates: [-0.0983, 51.5138]
  }
}

Rõ ràng, trong khoảng cách gần như vậy, có thể không phải lúc nào cũng khớp với nhiều điểm nổi bật, nhưng nếu bạn đang tìm kiếm một nhà hàng trong vòng một dặm đi bộ, điều đó có thể hoàn hảo!

Tìm Kiếm Trong Một Khu Vực

Chúng ta có thể cụ thể hơn nữa và tìm vị trí trong bán kính 5km. Điều này sẽ yêu cầu một chút toán học nhưng vẫn là một truy vấn đơn giản với $geoWithin:

javascript Copy
db.places.find({
  location: {
    $geoWithin: {
      $centerSphere: [[-0.0761, 51.508], 5 / 6378.1]
    }
  }
});

Tìm Kiếm Trong Một Khu Vực Tùy Chỉnh

Cuối cùng, chúng ta có thể làm điều gì đó cụ thể hơn như một hình đa giác. Giả sử chúng ta đang đi bộ qua Cầu Millennium từ Bắc London sang Nam London và muốn tìm kiếm một khu vực rất cụ thể:

javascript Copy
db.places.find({
  location: {
    $geoWithin: {
      $geometry: {
        type: "Polygon",
        coordinates: [[
           [-0.1145, 51.5073],
           [-0.1048, 51.5074],
           [-0.0931, 51.5070],
           [-0.0849, 51.5062],
           [-0.0738, 51.5050],
           [-0.0698, 51.4935],
           [-0.0869, 51.4900],
           [-0.1135, 51.4948],
           [-0.1160, 51.5015],
           [-0.1145, 51.5073]
        ]]
      }
    }
  }
});

Bây giờ, chúng ta có thể nhận lại các vị trí như Globe Theatre, Tate Modern, hoặc thậm chí là văn phòng chính của MongoDB London!

Sử Dụng Các Truy Vấn Địa Lý Trong Pipelines

Bạn cũng có thể tận dụng các truy vấn địa lý trong các pipeline tổng hợp bằng cách sử dụng $geoNear:

javascript Copy
db.places.aggregate([
  {
    $geoNear: {
      near: { type: "Point", coordinates: [-0.1278, 51.5074] },
      distanceField: "distanceMeters",
      maxDistance: 2000,
      spherical: true,
      query: { category: "history" }
    }
  },
  { $limit: 20 },
  { $project: { name: 1, category: 1, location: 1, distanceMeters: 1 } }
]);

Lưu ý: $geoNear phải là giai đoạn đầu tiên trong các tổng hợp.

Hiển Thị Dữ Liệu Địa Lý

Có nhiều cách để hiển thị dữ liệu này, bao gồm một số phương pháp tích hợp trực tiếp vào các sản phẩm của MongoDB, chẳng hạn như Compass hoặc Charts:

MongoDB Charts

Nếu bạn chưa sử dụng MongoDB Charts, đây là một nền tảng biểu đồ khá thú vị được tích hợp sẵn trong MongoDB Atlas, cho phép bạn tạo ra nhiều loại biểu đồ và bản đồ!

Ví dụ, bạn có thể sử dụng truy vấn khi xây dựng bản đồ để chỉ có một tập hợp con, cũng như thêm bản đồ cùng với các biểu đồ khác để tạo một bảng điều khiển.

MongoDB Compass

Bạn cũng có thể xem bản đồ như vậy trong MongoDB Compass nếu bạn nhấp vào tab Schemaphân tích tài liệu của bạn.

Vậy bạn có thể nghĩ ra những ý tưởng nào để sử dụng kiến thức mới về dữ liệu địa lý của mình? Hãy vui vẻ với nó!

Các Thực Hành Tốt Nhất

  • Đảm bảo chỉ mục địa lý được tạo đúng cách: Đảm bảo bạn tạo chỉ mục 2dsphere cho các trường dữ liệu địa lý.
  • Sử dụng GeoJSON: Lựa chọn GeoJSON cho tất cả các dữ liệu địa lý của bạn để dễ dàng truy vấn và xử lý.
  • Kiểm tra khoảng cách: Khi thực hiện các truy vấn gần, luôn kiểm tra khoảng cách để không lấy quá nhiều dữ liệu.

Cạm Bẫy Thường Gặp

  • Thứ tự tọa độ không chính xác: Đảm bảo bạn sử dụng thứ tự [kinh độ, vĩ độ] khi làm việc với tọa độ.
  • Sử dụng chỉ mục 2d cho dữ liệu hình cầu: Tránh sử dụng chỉ mục 2d cho dữ liệu địa lý hình cầu để tránh nhận kết quả sai.

Mẹo Hiệu Suất

  • Tối ưu hóa chỉ mục: Tạo chỉ mục hỗn hợp cho các truy vấn phức tạp để cải thiện hiệu suất.
  • Sử dụng các phép toán hình học: Tận dụng các phép toán hình học tối ưu hơn cho các truy vấn trong không gian.

Giải Quyết Vấn Đề

  • Nếu bạn gặp lỗi trong truy vấn, hãy kiểm tra định dạng GeoJSON và cấu trúc chỉ mục của bạn.
  • Sử dụng lệnh explain() để phân tích hiệu suất truy vấn của bạn.

Câu Hỏi Thường Gặp

1. GeoJSON là gì?
GeoJSON là định dạng dữ liệu địa lý dùng để biểu diễn các đặc điểm địa lý và thuộc tính của chúng.

2. Làm thế nào để tạo chỉ mục địa lý trong MongoDB?
Sử dụng lệnh db.collection.createIndex({ location: "2dsphere" }) để tạo chỉ mục địa lý.

3. Tôi có thể tìm kiếm theo khu vực nào trong MongoDB?
Bạn có thể sử dụng $geoWithin để tìm kiếm trong một khu vực cụ thể hoặc một hình đa giác.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào