【ITニュース解説】Working With Geo Location Data in MongoDB
2025年09月24日に「Dev.to」が公開したITニュース「Working With Geo Location Data in MongoDB」について初心者にもわかりやすく解説しています。
ITニュース概要
MongoDBではGeoJSON形式で位置情報データを定義し、2dsphereインデックスを作成すると、周辺検索や範囲検索が容易になる。`$near`や`$geoWithin`などのクエリを活用でき、CompassやChartsで地図上にデータを表示することも可能だ。位置情報サービス開発に役立つ。
ITニュース解説
MongoDBを使うと、位置情報データ(ジオデータとも呼ばれる)を非常に簡単に扱うことができる。データの保存方法がシンプルで、クエリの実行も効率的なため、「近くにあるものを探す」といった検索や、位置データを地図上に表示するといった作業が容易になる。この解説では、データのモデリングから、適切なインデックスの作成、ジオクエリの実行方法、そして結果の地図表示まで、基本的な使い方を順を追って説明する。
まず、データのモデリングから始める。MongoDBで位置情報データを保存し、操作する最適な方法は、GeoJSONと呼ばれる形式を使用することだ。GeoJSONは、JSON(JavaScript Object Notation)をベースにした地理空間データの交換フォーマットである。地理的特徴やそのプロパティ、空間的な範囲に関するデータを表現するために、いくつかのJSONオブジェクトタイプとその組み合わせ方が定義されている。このフォーマットは様々な位置関連データを格納できるが、ここでは最も基本的なPoint(点)タイプに焦点を当てる。Pointを保存するためには、「type」と「coordinates」のフィールドが必要となる。例えば、「York Minster」という場所のデータを保存する場合、次のような構造になる。「name」や「category」はアプリケーションで使うための情報だが、「location」フィールドの中にGeoJSON形式で位置情報が記述される。「type」は「Point」で、緯度経度を表す「coordinates」は配列になっている。ここで重要なのは、座標の順番が [経度, 緯度] であることだ。これは、一部の地図アプリケーションでの座標の扱い方と異なる場合があるため、注意が必要だ。
次に、位置情報に対してクエリを実行できるようにするために、特別な種類のインデックス(ジオ空間インデックス)を作成する必要がある。例えば、db.places.createIndex({ location: "2dsphere" }); というコマンドを実行すると、「location」フィールドにインデックスが作成される。さらに、場所のカテゴリも含めて複合インデックスを作成したい場合もある。その場合は、db.places.createIndex({ category: 1, location: "2dsphere" }); のように記述する。これにより、距離をチェックする前に、まずカテゴリで絞り込むといったクエリが可能になる。ここで 2dsphere タイプが重要な役割を果たす。このインデックスは、地球のような球体上のジオメトリを解釈するクエリをサポートする。もし球体データに対して 2d インデックスを使ってクエリを実行すると、不正確な結果が返されたり、エラーが発生したりする可能性がある。例えば、2d インデックスは極をまたぐような球体クエリをサポートしないため、2dsphere を使うのが適切だ。
MongoDBには、位置情報に関する様々なクエリを実行する機能がある。特に $near と $geoWithin という2つのオペレーターに焦点を当てて説明する。
最もシンプルなジオクエリ関連のオペレーターは $near で、これは指定された位置(これもPointタイプ)に最も近いドキュメントを返す。例えば、ロンドンの「Tower of London」から2,000メートル以内にある場所を探すクエリを考えてみよう。このクエリでは、「location」フィールドに対して $near を指定し、その中に $geometry で中心となる地点(ここではTower of Londonの座標)と、「$maxDistance」で最大距離(2000メートル)を設定する。このクエリを実行すると、Tower of Londonと「St. Paul's Cathedral」のような、指定された範囲内にある場所が結果として返される。この範囲は比較的狭いため、常に多くの主要なランドマークが見つかるわけではないが、例えば「徒歩1マイル圏内のレストランを探す」といった用途には非常に適している。
さらに具体的な範囲で場所を検索することも可能だ。例えば、中心点から半径5km以内の場所を探す場合は $geoWithin オペレーターを使用する。このクエリでは、「location」フィールドに対して $geoWithin を指定し、その中に $centerSphere を記述する。$centerSphere は球体上の円(球冠)の形状を表す。最初の値 [-0.0761, 51.508] は中心点(Tower of Londonの経度、緯度)だ。次の値 5 / 6378.1 は、半径5kmをラジアンに変換したもので、地球の平均半径(6378.1km)で割ることで計算される。
円形よりももっと複雑で、カスタムのエリア内で検索したい場合もあるだろう。例えば、ロンドンのミレニアムブリッジを渡って散歩する際に、非常に特定の多角形エリア内の場所を検索したい場合だ。このような場合も $geoWithin を使用するが、$geometry オペレーターで「type」を「Polygon」(多角形)に設定し、複数の座標を配列として提供する。この座標の配列は、多角形の各頂点を順に指定し、最後に最初の座標を再度指定することで形状を閉じる必要がある。この多角形クエリを実行すると、「Shakespeare’s Globe」や「Tate Modern」といった、指定したエリア内の場所が結果として得られる可能性がある。
ジオクエリは、アグリゲーションパイプラインの中でも利用できる。$geoNear を使うと、指定された地点からの距離に基づいてドキュメントを検索し、その距離情報も含めて結果を返すことが可能だ。例えば、中心点から2000メートル以内の「history」カテゴリの場所を最大20件まで検索し、名前、カテゴリ、位置、距離(distanceMetersというフィールドに格納される)のみを表示するパイプラインを組むことができる。$geoNear ステージは、near(中心点)、distanceField(距離を格納するフィールド)、maxDistance(最大距離)、spherical(球体計算を行うか)、query(追加のフィルタリング条件)といったオプションを持つ。この例はシンプルだが、この後にはさらに多くのパイプラインステージを追加できる。ただし、$geoNear はアグリゲーションパイプラインの最初のステージでなければならないという制約があるため注意が必要だ。
最後に、保存した位置データを地図上に表示する方法について説明する。MongoDBには、CompassやChartsといったツールが直接用意されており、これらを使って地図上にデータを可視化できる。 MongoDB Chartsは、MongoDB Atlas(MongoDBのクラウドサービス)に組み込まれたチャート作成プラットフォームであり、様々な種類のチャートはもちろん、地図も作成できる。Chartsで作成する地図はインタラクティブであり、特定のクエリに基づいて表示するデータを絞り込んだり、他のチャートと一緒にダッシュボードに組み込んだりすることも可能だ。 MongoDB Compassでも、スキーマタブをクリックしてドキュメントを分析すると、地図のような表示でデータを確認できる。 もちろん、Google Maps APIやMapboxといった外部の地図サービスを利用して、独自のアプリケーションで地図を表示することもできる。このように、新しく学んだ位置情報の知識を活用して、どのようなアイデアを実現できるか、様々な可能性を試してみるのは楽しいだろう。