【Node.js, MongoDB, Mongoose】Mongoose スキーマで 2D ジオインデックス付き配列内のオブジェクトを定義する方法
Mongoose スキーマで 2D ジオインデックス付きの配列内のオブジェクトを正しく定義する方法
このチュートリアルでは、Node.js、MongoDB、Mongoose を使用して、2D ジオインデックス付きの配列内のオブジェクトを Mongoose スキーマで正しく定義する方法を説明します。
要件
このチュートリアルを完了するには、次のものが必要です。
- Node.js がインストールされていること
手順
- スキーマを定義する
以下のスキーマは、locations
フィールドを持つ Place
ドキュメントを定義します。locations
フィールドは、緯度と経度を含むオブジェクトの配列です。このフィールドには 2D ジオインデックスが設定されています。
const mongoose = require('mongoose');
const placeSchema = new mongoose.Schema({
name: String,
locations: [{
type: {
type: String,
enum: ['Point'],
required: true
},
coordinates: {
type: [Number],
required: true,
index: '2dsphere'
}
}]
});
const Place = mongoose.model('Place', placeSchema);
- ドキュメントを作成する
以下のコードは、Place
ドキュメントを作成して保存する方法を示しています。
const place = new Place({
name: 'My Place',
locations: [{
coordinates: [-74.0060, 40.7128]
}]
});
place.save((err) => {
if (err) {
console.error(err);
return;
}
console.log('Place saved successfully!');
});
- ジオインデックスを使用してクエリを実行する
以下のコードは、Place
ドキュメントの locations
フィールド内の指定された座標に近い場所を検索する方法を示しています。
Place.find({
locations: {
$geoWithin: {
$geometry: {
type: 'Point',
coordinates: [-74.0060, 40.7128]
}
}
}
}).then((places) => {
console.log(places);
});
説明
placeSchema.locations.type
は、locations
フィールド内のオブジェクトの型を定義します。この場合、型はPoint
である必要があります。index: '2dsphere'
は、locations.coordinates
フィールドに 2D ジオインデックスを作成します。このインデックスを使用して、ジオクエリを実行できます。
補足
- 複数の座標を含むオブジェクトを保存するには、GeoJSON を使用できます。
- Mongoose には、ジオクエリを実行するためのさまざまなヘルパーメソッドが用意されています。詳細については、Mongoose のドキュメントを参照してください。
const mongoose = require('mongoose');
// データベースに接続
mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true, useUnifiedTopology: true });
// スキーマを定義
const placeSchema = new mongoose.Schema({
name: String,
locations: [{
type: {
type: String,
enum: ['Point'],
required: true
},
coordinates: {
type: [Number],
required: true,
index: '2dsphere'
}
}]
});
// モデルを作成
const Place = mongoose.model('Place', placeSchema);
// ドキュメントを作成
const place = new Place({
name: 'My Place',
locations: [{
coordinates: [-74.0060, 40.7128]
}]
});
// ドキュメントを保存
place.save((err) => {
if (err) {
console.error(err);
return;
}
console.log('Place saved successfully!');
});
// ジオインデックスを使用してクエリを実行
Place.find({
locations: {
$geoWithin: {
$geometry: {
type: 'Point',
coordinates: [-74.0060, 40.7128]
}
}
}
}).then((places) => {
console.log(places);
});
- このコードは、
mongodb://localhost:27017/test
データベースに接続します。 Place
は、placeSchema
から作成されたモデルです。place
は、Place
モデルの新しいインスタンスです。place.save()
は、place
ドキュメントをデータベースに保存します。Place.find()
は、Place
コレクションのクエリを実行します。$geoWithin
演算子は、指定された座標に近い場所を検索するために使用されます。
このコードは、Mongoose スキーマで 2D ジオインデックス付きの配列内のオブジェクトを定義する方法を理解するための出発点として使用できます。
Mongoose スキーマで 2D ジオインデックス付きの配列内のオブジェクトを定義するその他の方法
GeoJSON は、地理空間データをエンコードするための標準的なフォーマットです。Mongoose では、GeoJSON オブジェクトを直接スキーマに格納できます。
const placeSchema = new mongoose.Schema({
name: String,
locations: [{
type: {
type: String,
enum: ['Point'],
required: true
},
coordinates: {
type: mongoose.Schema.Types.GeoJSON,
required: true
}
}]
});
この例では、locations.coordinates
フィールドは GeoJSON
型として定義されています。これにより、緯度と経度を含む GeoJSON オブジェクトを格納できます。
カスタムタイプを使用する
Mongoose では、カスタムタイプを作成して、スキーマで使用できます。これにより、独自のロジックを定義したり、既存のライブラリと統合したりすることができます。
const pointSchema = new mongoose.Schema({
type: {
type: String,
enum: ['Point'],
required: true
},
coordinates: {
type: [Number],
required: true
}
});
const placeSchema = new mongoose.Schema({
name: String,
locations: [pointSchema]
});
この例では、pointSchema
は、緯度と経度を含むオブジェクトを定義するカスタムタイプです。placeSchema
の locations
フィールドは、pointSchema
の配列として定義されています。
サブドキュメントは、別のドキュメントに埋め込まれたドキュメントです。Mongoose では、サブドキュメントを使用して、複雑な関係をモデル化できます。
const locationSchema = new mongoose.Schema({
type: {
type: String,
enum: ['Point'],
required: true
},
coordinates: {
type: [Number],
required: true
}
});
const placeSchema = new mongoose.Schema({
name: String,
locations: [locationSchema]
});
- GeoJSON を使用する場合は、緯度と経度を含むシンプルなオブジェクトを格納する必要があります。
- カスタムタイプを使用する場合は、独自のロジックを定義したり、既存のライブラリと統合したりする必要があります。
- サブドキュメントを使用する場合は、複雑な関係をモデル化する必要があります。
node.js mongodb mongoose