[Node.js] Database - MongoDB


これは、
  • 以前の文書[Node.js] Express - Routerのコードです.
  • SQL vs NoSQL

  • でよく使用されるデータベースは、SQLとNoSQLの2種類に大きく分けられます.
  • 私たちがどんなプロジェクトを行っても、サービスを作成しても、どんなDBを使っても悩ましいです.
  • という2つの概念は、反対の概念というより、「異なる」概念と理解されている.
  • それぞれの特徴を見て、どのような場合にどのDBを使うべきかを考えてみましょう.
  • (1) SQL

  • 構造化クエリ言語略語
  • データが固定された列と行を持つテーブルに格納される場合、通常はSQLと呼ばれます.
  • リレーショナル・データベースとも呼ばれます.
  • 代表的なものはMySQL、Oracle、MySQLなどです.
  • 「アーキテクチャ」と呼ばれるデータテーブルとして管理される.
  • 各テーブル情報は比較的明確で、管理と理解が容易である.
  • (2) NoSQL

  • リレーショナル・データベースを使用しない方法です.
  • は主に非リレーショナル・データベースであるが、リレーショナル・データベース・システムを完全に使用できない方法ではない.
  • SQLの「アーキテクチャ」のように固定された形式ではないため、データの変更と管理を柔軟に行うことができます.
  • ですが、データが複雑になる可能性があり、SQLに比べてデータベースの理解が難しくなります.
  • サービスを流動的に変更する必要があるベンチャー企業では、主にこの方式が好きだ.
  • 代表的なものはMongoDB、Hadoop.
  • データは主にJson形式{'key':'value'}からなる.
  • MongoDB

  • MonboDBは典型的なNoSQLの1つです.
  • の簡単なプロジェクトを通じて、MongoDBの使い方を理解します.
  • MongoDBを使用するには、MongoDB、Robo 3 Tをインストールし、Mongooseライブラリを使用します.
  • (1)MongoDB(Mac)の取り付け


    まずTerminalを実行し、次のコマンドでMongoDBをインストールします.
    // 커스텀 홈브루 탭 세팅
    brew tap mongodb/brew
    
    // MongoDB 설치
    brew install mongodb-community
    
    // MongoDB 실행
    brew services start mongodb-community
  • Webブラウザを開き、http://localhost:27017アドレスに接続すると、次の画面が表示されると、正常にインストールおよび実行されていることを示します.

  • (2)Robo 3 T取付


    Robo 3 Tは、MongoDBデータベースを直感的に見て操作できるGUIプログラムです.
  • Robo 3 T公式サイトからダウンロード
  • の上のウェブサイトで、オペレーティングシステムに適したバージョンをダウンロードしてインストールすればいいです.
  • の上の画面の左上をクリックすると、パソコンのアイコンにMongoDB Connectionsウィンドウが表示されます.
  • Createをクリックし、「Name」に接続名を作成します.
  • は、ローカル環境でデータベースを構築するため、アドレスとポートは変更されません.
  • に必要な名前で接続を作成し、「Save」をクリックすると、上記の画面が表示されます.
  • 現在、ローカル環境でMongoDBを通じてデータを管理する準備ができています.
  • (3)Mongooseインストール

  • MongooseはNodeです.jsでは、MongoDB連動ライブラリで最も多く使用されています.
  • NoSQLには「アーキテクチャ」という概念はありませんが、RDBのように「アーキテクチャ」を使用できます.
  • のインストールはnpmで非常に簡単に行えます.
  • まず、作成中のノード.jsプロジェクトで次のコマンドを実行します.
  • npm i mongoose
  • は現在、MongoDBを使用する準備ができています.
  • Mongooseによるデータ処理


    Mongooseを通して、MongoDBのCRUD機能を知る.

    (1)データベースモジュールの作成

  • Mongooseライブラリをrequire()で読み込みます.
  • 接続
  • の上に作成されたMongoDB接続.
  • 使用するデータベース名
  • を決定します.
  • エクスポートモジュールは外部で使用されます.
  • ビット順で簡単に行います
  • まず、プロジェクトにschemasフォルダを作成し、インデックスを作成します.jsファイルが生成されました.
    // ./schemas/index.js
    
    // mongoose 라이브러리 불러오기
    const mongoose = require('mongoose');
    // connect 객체 생성
    // connect 주소는 항상 mongodb://~~~ 의 형식이어야 한다. 
    // 주소 뒤의 'mydb' 부분에, Database 이름을 작성해주면 된다. 
    const connect = () => {
        mongoose
            .connect('mongodb://localhost:27017/mydb', {
                ignoreUndefined: true,
            })
            .catch(err => console.log(err));
    };
    
    // 외부에서 사용하기 위해, 모듈을 내보낸다.
    module.exports = connect;

    (2)データベースへの接続

  • を実行するファイルはappです.jsファイルなので、このファイルでモジュールを使ってみます.
  • Expressとともに使用され、以下のようになります.
  • // express
    const express = require('express');
    const app = express();
    const port = 8080;
    
    // mongoose
    // index.js 파일은 이름을 생략할 수 있기 때문에, ./schemas 만 입력
    const connect = require('./schemas');
    // connect mongoose
    connect();
  • ビットに示すように、コードを記述し、アプリケーションを作成します.jsで実行する場合.../schema/index.jsファイルで作成した内容に従って、MongoDBサーバに接続するのは正常です.
  • (3)Schema,モデルの作成

  • MongooseはRDBのようにSchemaを作成して、どのように作成するかを見ることができると言っています.
  • アーキテクチャフォルダの「goods」.js'ファイルを作成し、次のコードを作成します.
  • const mongoose = require('mongoose');
    
    const goodsSchema = new mongoose.Schema({
        goodsId: {
            type: Number,
            required: true,
            unique: true,
        },
        name: {
            type: String,
            required: true,
            unique: true,
        },
        thumbnailUrl: {
            type: String,
        },
        category: {
            type: String,
        },
        price: {
            type: Number,
        },
    });
    
    // mongoose.model() 의 첫번째 인자 'Goods'가 Collection의 이름이 되는 것이다.
    module.exports = mongoose.model('Goods', goodsSchema);
  • は非常に直感的なので、あまり説明しにくいように見えます.
  • requiredは必須値であり、uniqueは繰り返し不可能な値である.
  • の最後の行コードでは、モデルが私たちのデータをデータベースセットに定義し、JavaScriptとインタラクティブなオブジェクトと見なす「model」と呼ばれる方法を使用しました.(ここで、データベース集合はRDBにおけるTableと見なすことができる.)
  • すなわち、このモデルオブジェクトを使用して、データベースの対応するセットにデータを格納し、変更および削除することができる.
  • (4)ルーター接続

  • 以前のプロジェクトではRouterが使用されていたため、DBへのアクセスもこのRouterによって実現された.したがって、生成したRouterファイルで使用するためにコードを作成します.
  • // ./routes/goods.js
    
    const express = require('express');
    const router = express.Router();
    
    // goods에서 exports 한 model 객체를 그대로 'Goods' 변수에 할당한다.
    const Goods = require('../schemas/goods');
    前の
  • に示すように、require()を使用してモデルを取得すると、使用できます.
  • (5)CRUDの実装を試みる

  • やっとデータベースでデータの読み取り、書き込み、修正、削除ができます.
  • 次のコードでは、CRUDメソッドについて簡単に説明します.
    // ./routes/goods.js
    
    const express = require('express');
    const router = express.Router();
    const Goods = require('../schemas/goods');
    
    // 상품 추가 (Create)
    router.post('/goods/:goodsId/cart', async (req, res) => {
        const { goodsId } = req.params;
        const { quantity } = req.body;
    
        // 유의사항: .find()는 Promise 객체를 반환하기 때문에, await/async를 사용한다.
        const existsCarts = await Cart.find({ goodsId: Number(goodsId) });
        if (existsCarts.length) {
            return res.status(400).json({
                success: false,
                errorMessage: '이미 장바구니에 있는 상품입니다.',
            });
        }
    
        await Cart.create({ goodsId: Number(goodsId), quantity });
        res.json({ success: true });
    });
    
    // 전체 목록 조회 (Read)
    router.get('/goods', async (req, res) => {
        const { category } = req.query;
        console.log('category?', category);
    
      	// 유의사항: .find()는 Promise 객체를 반환하기 때문에, await/async를 사용한다.
        const goods = await Goods.find({ category });
        res.json({
            // 객체의 이름이 key와 똑같다면, 약식으로 하나만 써주어도 된다.
            // 아래 코드는 goods: goods 와 동일하다.
            goods,
        });
    });
    
    // 상품 수량 수정 (Update)
    router.put('/goods/:goodsId/cart', async (req, res) => {
        const { goodsId } = req.params;
        const { quantity } = req.body;
        console.log(`goodsId: ${goodsId}`);
        console.log(`quantity: ${quantity}`);
    
        // 유의사항: .find()는 Promise 객체를 반환하기 때문에, await/async를 사용한다.
        const existsCarts = await Cart.find({ goodsId: Number(goodsId) });
        console.log(`existsCarts: ${existsCarts}`);
        if (!existsCarts.length) {
            return res.status(400).json({
                success: false,
                errorMessage: '장바구니에 상품이 없습니다.',
            });
        }
    
        // 유의사항: .updateOne()은 Promise 객체를 반환하기 때문에, await/async를 사용한다.
        await Cart.updateOne({ goodsId: Number(goodsId) }, { $set: { quantity } });
        res.json({ success: true });
    });
    
    // 상품 삭제 (Delete)
    router.delete('/goods/:goodsId/cart', async (req, res) => {
        const { goodsId } = req.params;
    
        // 유의사항: .find()는 Promise 객체를 반환하기 때문에, await/async를 사용한다.
        const existsCarts = await Cart.find({ goodsId: Number(goodsId) });
        if (existsCarts.length) {
            await Cart.deleteOne({ goodsId: Number(goodsId) });
        }
    
        res.json({ success: true });
    });
  • find()、updateOne()などの方法でPromiseオブジェクトが返されるため、async/awaitまたはPromise構文で記述する必要があります.