駆け出しのエンジニア日記

プログラミング言語勉強中の奮闘日記

MongoDBのリレーション:1対たくさん

〜MongoDBのリレーション〜

今回は1対たくさんの場合を見ていきます。

例えば、商品の生産管理でどの農場でどの商品が作られているかの情報を提供したい時

のケースで記述していきます。

早速書いていきます。

・1対たくさん(One to Many)

//1対たくさんのリレーション
const mongoose = require('mongoose');
const { Schema } = mongoose;
mongoose.connect('mongodb://localhost:27017/relationshipDemo',
{ useNewUrlParser: true, useUnifiedTopology: true })
.then(() => {
console.log('MongoDBコネクションOK!!');
})
.catch(err => {
console.log('MongoDBコネクションエラー!!!');
console.log(err);
});

const productSchema = new Schema({
name: String,
price: Number,
season: {
type: String,
enum: ['spring', 'summer', 'fall', 'winter']
}
})
const farmSchema = new Schema({
name: String,
city: String,
// 商品の紐付けは「ID」 productSchemaと紐付けるための定義
//refを定義することで、Productモデルと紐づいていることが確認できる
products: [{ type: Schema.Types.ObjectId, ref: 'Product' }]
})
//モデル作成
const Product = mongoose.model('Product', productSchema);
const Farm = mongoose.model('Farm', farmSchema);

まずはスキーマ定義とモデル作成から行います。

mongoose の場合、スキーマ定義の部分で「 ref 」を使うことでリレーションを表現す

ることができます。
mongodb は コレクションに ドキュメント が作成された際に一意なObjectIdが生成され

るため、これを外部キーのように利用してリレーションを表現することが可能です。

次に農場を新規作成する関数を作成します。

const makeFarm = async () => {
const farm = new Farm({ name: 'まったり牧場', city: '淡路市' });
const melon = await Product.findOne({ name: 'メロン' });
farm.products.push(melon);
await farm.save();
}

makeFarm();

実行すると、「まったり牧場」という農場が作成されます。

商品(オブジェクト)としても「メロン・498・夏」の情報になります。

※メロンに関しては先に下記データを挿入しています。

Product.insertMany([
{ name: 'メロン', price: 498, season: 'summer' },
{ name: 'スイカ', price: 498, season: 'summer' },
{ name: 'アスパラガス', price: 298, season: 'spring' }
]);

 

牧場は一つの商品だけということは少なく、複数(たくさん)の商品を扱うことが前提

となるので、これが「1対たくさん」の例に挙げております。

データサイズが巨大になる可能性がある場合や1対数個の直接記述するよりは、

柔軟に使えると感じます。