Edited at

mongooseで地理情報を扱う(aggregate().near())


前提


概要

いろいろあるけど、Aggregateの$geoNearを使うと距離も取得できていい感じ

Mongooseではnearなので注意。なぜgeoNearではないのかは不明


サンプルソース

mongoose接続情報、省略

Mongoose Model Place


../models/place

const mongoose = require('mongoose')

const Schema = mongoose.Schema;
const geoSchema = new Schema({
type : { type : String , default : 'Point'},
coordinates : { type : [Number] , default : [0,0] }
});

const placeSchema = new Schema({
place_id : { type : String, required : [false, 'Place id is required'], default:'new' },
place_name : { type : String, default:'new place' },
location : { type : geoSchema , index: '2dsphere', default: geoSchema },
lastupdate : { type : Date, default: Date.now},
});

const Place = mongoose.model('Place', placeSchema);
module.exports = {Place}



実行用ファイル

require('../config/config.js')

const { mongoose } = require("../db/mongoose");
const { Place } = require("../models/place");

//サンプルデータ定義
// http://gihyo.jp/dev/serial/01/mongodb/0009
const places=[
{ place_id : '1', place_name : '五反田', location:{ type:'Point', coordinates:[ 139.723822, 35.625974 ]}},
{ place_id : '2', place_name : '恵比寿', location:{ type:'Point', coordinates:[ 139.710070, 35.646685 ]}},
{ place_id : '3', place_name : '新宿', location:{ type:'Point', coordinates:[ 139.700464, 35.689729 ]}},
{ place_id : '4', place_name : '新大久保',location:{ type:'Point', coordinates:[ 139.700261, 35.700875 ]}},
{ place_id : '5', place_name : '池袋', location:{ type:'Point', coordinates:[ 139.711086, 35.730256 ]}},
{ place_id : '6', place_name : '上野', location:{ type:'Point', coordinates:[ 139.777043, 35.713790 ]}},
{ place_id : '7', place_name : '品川', location:{ type:'Point', coordinates:[ 139.738999, 35.628760 ]}}
]
// テーブル初期化
async function populatePlaces() {
await Place.deleteMany({});
await Place.insertMany(places);
}

//近い順にPlaceデータ取得 GeoNear(aggregate)
//https://mongoosejs.com/docs/api.html#aggregate_Aggregate-near
async function geonear(limit){
const results = await Place.aggregate()
.near({
near: { type : "Point", coordinates: [139.701238, 35.658871] }, //渋谷駅
spherical: true,
distanceField: "distance", //メートル
})
.limit(limit)
console.log(results)
}

//メイン関数
async function main(){
await populatePlaces() //コレクション初期化
await geonear(3) //近い方から3つ表示
}
main()



実行結果

恵比寿、新宿、五反田が帰ってくる。

距離はdistanceにメートルで保存されている。

image.png

以上。