Mongoose 2d geo index 解説
Mongooseで配列オブジェクトに2d geo indexを正しく定義する方法 (日本語)
Mongooseは、Node.jsアプリケーションでMongoDBとやり取りするためのオブジェクトデータモデリングツールです。配列オブジェクトに2d geo indexを定義することで、地理空間データのクエリを効率的に実行することができます。
基本的な構造
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const locationSchema = new Schema({
type: { type: String, required: true, en um: ['Point'] },
coordinates: { type: [Number], required: true }
});
const mySchema = new Schema({
locations: [locationSchema]
});
const MyModel = mongoose.model('MyModel', mySchema);
- 配列オブジェクト (
locations
):この配列は、各ドキュメントの複数の地理空間ポイントを格納します。 locationSchema
:個々の地理空間ポイントの構造を定義します。type
: ジオメトリの種類(ここではPoint
)。coordinates
: 経度と緯度の配列。
2d geo indexの定義
mySchema.index({ locations: '2dsphere' });
'2dsphere'
:2d球面インデックスを指定します。これは、地球の球面形状を考慮したインデックスであり、地理空間クエリに最適です。
クエリ例
MyModel.find({
locations: {
$geoWithin: {
$centerSphere: [[longitude, latitude], radiusInRadians]
}
}
}).exec((err, results) => {
// resultsは、指定された範囲内のドキュメントの配列です
});
$centerSphere
: 円形の範囲を定義します。[longitude, latitude]
: 円の中心座標。radiusInRadians
: 半径(ラジアン単位)。
$geoWithin
: 指定した範囲内に含まれるドキュメントを検索します。
注意点
- 2d geo indexは、地理空間クエリのパフォーマンスを大幅に改善しますが、インデックスのサイズが大きくなる可能性があります。適切なインデックス戦略を検討してください。
- 半径はラジアン単位で指定する必要があります。
- 経度は最初に、緯度は次に指定してください。
- 緯度と経度は、それぞれ
Number
型で定義されている必要があります。
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const locationSchema = new Schema({
type: { type: String, required: true, en um: ['Point'] },
coordinates: { type: [Number], required: true }
});
const mySchema = new Schema({
locations: [locationSchema]
});
const MyModel = mongoose.model('MyModel', mySchema);
mySchema.index({ locations: '2dsphere' });
MyModel.find({
locations: {
$geoWithin: {
$centerSphere: [[longitude, latitude], radiusInRadians]
}
}
}).exec((err, results) => {
// resultsは、指定された範囲内のドキュメントの配列です
});
Mongoose 2d geo index 解説
Mongooseの2d geo indexは、地理空間データのクエリを高速化するためのインデックスです。このインデックスは、地球の球面形状を考慮して構築されるため、地理的な位置関係に基づくクエリに最適です。
- 地球の球面形状を考慮
2d geo indexは、地球の球面形状を考慮しているため、正確な地理空間クエリを実行することができます。 - 高速な地理空間クエリ
2d geo indexを使用することで、地理的な位置関係に基づくクエリを大幅に高速化することができます。
mySchema.index({ locations: '2dsphere' });
'2dsphere'
:2d球面インデックスを指定します。
MyModel.find({
locations: {
$geoWithin: {
$centerSphere: [[longitude, latitude], radiusInRadians]
}
}
}).exec((err, results) => {
// resultsは、指定された範囲内のドキュメントの配列です
});
$centerSphere
: 円形の範囲を定義します。
- 2d geo indexは、インデックスのサイズが大きくなる可能性があります。適切なインデックス戦略を検討してください。
他のアプローチ
GeoJSONオブジェクトの使用
- 2d geo indexを定義する必要はありませんが、クエリのパフォーマンスが低下する可能性があります。
- GeoJSONの仕様に準拠した地理空間オブジェクトを直接定義します。
const mySchema = new Schema({
location: {
type: { type: String, enum: ['Point'] },
coordinates: { type: [Number] }
}
});
カスタムインデックスの使用
- 2d geo indexよりも柔軟性がありますが、実装が複雑になる可能性があります。
- MongoDBのネイティブインデックスを使用して、地理空間クエリを最適化します。
mySchema.index({ 'location.coordinates': '2dsphere' });
MongoDBの地理空間オペレーターの使用
- MongoDBの組み込みの地理空間オペレーターを使用して、地理空間クエリを実行します。
MyModel.find({
location: {
$near: {
$geometry: { type: 'Point', coordinates: [longitude, latitude] },
$maxDistance: distanceInMeters
}
}
});
mySchema.index({ locations: '2dsphere' });
MyModel.find({
locations: {
$geoWithin: {
$centerSphere: [[longitude, latitude], radiusInRadians]
}
}
}).exec((err, results) => {
// resultsは、指定された範囲内のドキュメントの配列です
});
node.js mongodb mongoose