地理空間インデックスの概要
MongoDBでは,
MongoDBの地理空間インデックスは,
こちらに,
バージョン | リリースされた機能 |
---|---|
1. | 地理空間インデックスをサポート |
1. | 球面空間でのクエリをサポート |
2. | GeoJSONオブジェクトをサポート |
それではさっそく地理空間インデックスを使ってみましょう。
- ※1)
- 2.
4で追加されたGeoJSONについては, この連載の前回の記事 (第8回 「リリース間近! MongoDB 2. )4の新機能」 をお読みください。
シンプルなデータで地理空間インデックスを使ってみる
2dインデックスの作成
地理空間インデックスを使うためには,
> db.yamanotesen.ensureIndex( { loc : "2d" } );
次にデータのinsertを行います。
データの準備
地理空間インデックスを使うため,
駅 | 経度 | 緯度 |
---|---|---|
五反田 | 139. | 35. |
恵比寿 | 139. | 35. |
新宿 | 139. | 35. |
新大久保 | 139. | 35. |
池袋 | 139. | 35. |
上野 | 139. | 35. |
品川 | 139. | 35. |
経度・
> db.yamanotesen.insert({ name:"五反田",loc: [ 139.723822, 35.625974 ] }); > db.yamanotesen.insert({ name:"恵比寿",loc: [ 139.710070, 35.646685 ] }); > db.yamanotesen.insert({ name:"新宿",loc: [ 139.700464, 35.689729 ] }); > db.yamanotesen.insert({ name:"新大久保",loc: [ 139.700261, 35.700875 ] }); > db.yamanotesen.insert({ name:"池袋",loc: [ 139.711086, 35.730256 ] }); > db.yamanotesen.insert({ name:"上野",loc: [ 139.777043, 35.713790 ] }); > db.yamanotesen.insert({ name:"品川",loc: [ 139.738999, 35.628760 ] });
- ※2)
- 後ほど紹介する球面空間での検索において,
経度と緯度の順番が重要になります。データには, ['経度', '緯度']の書式でinsertしましょう。
準備は整いましたので,
近傍を検索するクエリ
近傍の検索には,
> db.yamanotesen.find({ loc : { $near : [ 139.701238, 35.658871 ] }}).limit(3)
今回準備した7つの駅で,
> db.yamanotesen.find({ loc : { $near : [ 139.701238, 35.658871 ] }},{"_id":0}).limit(3) { "name" : "恵比寿", "loc" : [ 139.71007, 35.646685 ] } { "name" : "新宿", "loc" : [ 139.700464, 35.689729 ] } { "name" : "五反田", "loc" : [ 139.723822, 35.625974 ] }
検索結果の詳細情報取得
geoNearコマンドを使用することで,
> db.runCommand({'geoNear':'yamanotesen', near : [ 139.701238, 35.658871 ], num: 1}) { "ns" : "test.yamanotesen", "near" : "1110100101001011001100110110111110110111011101111101", "results" : [ { "dis" : 0.015050010631232593, "obj" : { "_id" : ObjectId("514a653517ca6b06a3266e26"), "name" : "恵比寿", "loc" : [ 139.71007, 35.646685 ] } } ], "stats" : { "time" : 0, "btreelocs" : 0, "nscanned" : 5, "objectsLoaded" : 3, "avgDistance" : 0.015050010631232593, "maxDistance" : 0.015066109444883333 }, "ok" : 1 }
経度・
0.
015050010631232593×111. 262283=約1. 7km
となります。
地球は球面なので平面空間で計算すると誤差が出てしまいます。MongoDBは球面空間でのクエリもサポートしていますので,
- ※3)
- 正確には経度1度の距離は緯度によって変わります。