7
9

More than 3 years have passed since last update.

【mongoDB】Mongooseチートシート 

Last updated at Posted at 2020-12-23

Mongooseとは

どんな種類のデータを保存できるかを定義する「スキーマ」を持つモデルを構築できる。
モデルはjavasrciptにおけるクラスのようなもの。
Mongooseはモデルを使って、データベースクエリの組織化を行う。

よく使うクエリメソッド

find : マッチするドキュメントの配列を返す

Human.find({name:"taro" }, (err, result)=> {
  //処理結果
});

findOne : 配列でなく一つのドキュメントを返す。 例) Human.findOne({name: "Taro"})
findById : ObjectIdeで一致するオブジェクトを返す。 例)Human.findOne("kjfkajjdfkjagkja")
remove : データーベースにあるドキュメントを削除する。
find().pretty() : .pretty()をつけることにより結果がインデントされる。
```
これらのクエリはプロミスを返すので、結果処理には then や catchでつなげる必要がある。

Node.jsアプリケーションにMongooseを設定する。

//mongooseをロード
const mongoose = require("mongoose");
//データーベース接続を設定
mongoose.connect(
  "mongodb://<username>:<password>@localhost:27017/<dbname>",
  {userNewParser:true}
);

mongoose.set("useCreateIndex", true);

//データーベースをdb変数に代入
const db = mongoose.connection;

//接続メッセージをログに出力する
db.once("open",()=>{
  console.log("success connect");
});

スキーマを作る

mongoose.Schemaメソッドのコンストラクタにパラメーター(オブジェクト)を与えることによって、スキーマオブジェクトを構築できる。

const mongoose = require("mongoose");
const humanSchema = new mongoose.Schema({
  name:String,
  age:Number
});

スキーマのデータ型について
https://mongoosejs.com/docs/schematypes.html

仮想属性を設定する

const humanSchema = new mongoose.Schema({
  name:String,
  age:Number
});

humanSchema.virtual("info").get(function () { //実際の属性としてはデーターベースに保存されないが、インスタンスから取り出せる。
  return `${this.name} ${this.age}`;
});

バリデーションを設定する

"use strict";

const mongoose = require("mongoose");

const humanSchema = new mongoose.Schema({
  name: {  //nameのバリューにオブジェクトで渡す。
    type: String,
    required: true,  //必須
    unique: true     //ユニーク
  },
  age: {
    type: Number,
    min: [18, "Too short"],//最小値エラーメッセージ を設定
    max: 99 //最大値
  }
});

module.exports = mongoose.model("Human", humanSchema);

スキーマをモデルに適用する。

const Human = mongoose.model("Human", humanSchema)
//mongoose.modelメソッドに("モデル名", スキーマ)を引数に与えて、実体化してHumanに格納する。

エクスポート

module.exports = mongoose.model("Human", humanSchema);

スキーマにインスタンスメソッドを設定する。(getInfoと言う名のメソッドを設定)

humanSchema.methods.getInfo = function () {
  return `Name: ${this.name} Age: ${this.age}`;
};

モデルからオブジェクトを作る。

new → saveの方法

let human1 = new Human({ //newキーワードでオブジェクトを生成。
  name: "Taro",
  age:20
});
human1.save((error, savedDocument) => {  //saveメソッドで保存
  //引数に、エラー処理、または返されるデーターの処理をコールバック関数で渡す。
  if (error){
   console.log(error)
  }
  console.log(savedDocument);

createの方法

Human.create({
  name: "Taro",
  age:20
  },
  function(error,savedDocument){
  if (error){
   console.log(error)
  }
  console.log(savedDocument);
  }
};
//createは、newとsaveを一気に行う。(パラメータ, コールバック)が引数。

フックを設定する。

models/human.js
humanSchema.pre("save", function(next) {
  //saveされる前に実施する処理
  //この中でのthisは呼び出し元、つまりhumanSchemaが格納される。
  next();
}

モデルを組織化する

モデルファイルにスキーマとモデルを定義する。

models/human.js
const mongoose = require("mongoose");

const humanSchema = mongoose.Schema({ //mongoose.Schemaメソッドでスキーマを作る
  name:String,
  age:Number
});

module.exports = mongoose.model("Human", humanSchema); 
//mongoose.modelメソッドでスキーマをHumanモデルに適用しエクスポート

他のファイルからHumanモデルを呼び出す。

main.js
const Human = require("./models/human");

モデル間のリレーションを設定する

"use strict";

const mongoose = require("mongoose");

const humanSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    unique: true
  },
  age: {
    type: Number,
    min: [18, "Too short"],
    max: 99 //最大値
  }
  father: { //Fatherモデルに所属//単数形
    type: mongoose.Schema.Types.ObjectId, //外部キー
    ref: "Father" //参照モデル
    }
  children: [{ //Childモデルを所有//複数形//配列リテラルで囲む
    type: mongoose.Scheme.Types.ObnectId,
    ref: "Child"
    }]
});

module.exports = mongoose.model("Human", humanSchema);

実際にドキュメント同士を関連づける

//所有の場合
human1.children.push(child1);
human1.save();
 //human1インスタンスのchildrenプロパティにchild1ドキュメントを追加
//もしくは、直接ObjectIDを追加する。
human1.children.push("オブジェトID");
human1.save();

//所属の場合
human1.father = father1;
human1.save();

関連付いたドキュメントを取得する。

Human.populate(human1, "children"); //human1に紐づくchildドキュメントを連結してオブジェクト化する。

親を指定して、関連づいたドキュメントを取得する。

Human.findOne({ name: "taro" }).populate({"children" }).exec((error, data) => {
  console.log(data);
}
)

データベース内のドキュメントを検索する

const Human = require("./models/human");

Human.findOne({name:"Taro"}).where("age":20);
//findOne(合致するものを取得).where(絞り込み条件);

クエリを実行する

let query = Human.findOne({name:"Taro"}).where("age":20);

query.exec((error, data)=>{  //execで実行し、処理を引数にとる。返るデータはdataに渡す。
  if(data){
    console.log(data.name)
  }
);

検索とアップデートを同時に行う

 <モデル>.findByIdAndUpdate(<id>, {
      $set: <オブジェクト>//$setのバリューの値でアップデート
    })

検索と削除を同時に行う

<モデル>.findByIdAndRemove(<id>)

プロミスを使うための設定

mongoose.Promise = global.Promise

シードモジュールの作成

seed.js
const mongoose = require("mongoose"); //モジュールロード

const Human = require("./models/Human.js");
//保存するモデルの読み込み必要

mongoose.connect(  //接続設定
  "mongodb://localhost:27017/my_db",
  {userNewParser:true}
);

mongoose.set("useCreateIndex", true);

mongoose.connection;

const humans = [ //シードデーター
  {name:"Taro",
   age:20
  },
  {name:"Ken",
   age:30
  },
  {name:"Jiro",
   age:40
  }
];

Human.deleteMany() //既存のデータをクリア
  .exec()
  .then(() => {
     console.log("Empty"); //確認用ログ
  });

let commands = []; //シーダー配列用

humans.forEeach((c)=> { //commands配列にシーダーをループで全て追加
  commands.push(Human.create({
    name:c.name,
    email:c.age
    }));
});

Promise.all(commands) //全てのプロミス解決後の処理
  .then(r => {
    console.log(JSON.stringify(r));
    mongoose.connection.close();
  })
  .catch(error => {
    console.log($error);
});
7
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9