BETA

Express編-nodejsからmongodbの操作を少しづつ改良してみる

投稿日:2018-12-01
最終更新:2018-12-02
  • switch編-nodejsからmongodbの操作を少しづつ改良してみる、こちらからの続きになります。

  • コードをもう少し改善していきたいのですが、http はとっつきにくく扱いづらい印象です。

  • 前回の記事では、switch文とhttp を使ってブラウザー入力をしていましたが、この基本機能を備えているのがExpressです。
  • Expressのチュートリアルやガイドを見ていて,Expressは、コールバック関数を順番に処理する仕様で、http命令でスイッチ処理することが出来て 前回のhttpの親玉にあたるプログラムだと感じました。
  • Expressガイドは、日本語訳も初心者に優しく分かりやすいです。 mongodbのガイドは初心者にあまり優しくないですが。。。コレクションメソッドの項目だけみればいいのでまぁ構いませんが。

  • まだ見ていない方は、この記事を読むより、Expressガイドを見ることをおすすめします。(笑)

  • http から Express に実装を変更したいと思います

  • Express をインストールしておきます

yarn add express
  • myExpress.js
var express = require('express');
var app = express();

// respond with "hello world" when a GET request is made to the homepage
app.get('/', function(req, res) {
  res.send('hello world');
});

app.get('/10', (req, res) => {
    res.send('削除完了')
})

app.get('/20', (req, res) => {
    res.send('作成完了')
})

app.get('/30', (req, res) => {
    res.send('表示完了')
})

app.listen(3000, () => console.log("connecting... localhost:3000"))
  • 実行して、ブラウザーURL欄に入力してみてください。 ポート番号が変わっていますので注意してください
  • http://localhost:3000/10
  • http://localhost:3000/20
  • http://localhost:3000/30

  • http は日本語使うと文字化けしていましたが、Express は問題ないですね。

  • default で日本語対応していて、 スイッチ文を意識しなくてもいいですし、こちらのほうが実装も簡単そうです。

  • それでは、mongodb用のコードに実装してみます。

const MongoClient = require('mongodb').MongoClient
const assert = require('assert')
const express = require('express')
const app = express()

const url = 'mongodb://localhost:27017/myproject'
const dbName = 'myproject'
const client = new MongoClient(url)
const lib = require('./libCallback.js')
const { insertDocuments, insertOneDocument, findDocuments, deleteManyDocuments } = lib


client.connect(err => {
    assert.equal(null, err)
    console.log("Connected successfully to server")
    const db = client.db(dbName)


    app.get('/', (req, res) => {
        console.log(req.query)
        res.send('hello')
    })
    app.get('/delete', (req, res) => {
        console.log(req.query)
        deleteManyDocuments(db, (result) => {
            console.log(result.result)
        })
        res.send('delete done')
    })
    app.get('/insertMany', (req, res) => {
        console.log(req.query)
        insertDocuments(db, (result) => {
            console.log(result.result)
        })
        res.send('insert done')
    })
    app.get('/find', (req, res) => {
        console.log(req.query)
        findDocuments(db, (docs) => {
            console.log(docs)
        })
        res.send('find done')
    })

    app.listen(3000, () => console.log("connecting"))

})
  • クリック仕様にするので、数字から内容を示すように改めました。
  • htmlも書き換えて、見ましょう
<DOCTYPE html>
<html>
  <head>
    <title>mongodb switcher</title>
  </head>
  <body>
    <h1>mongodb コレクションメソッドコントロール</h1>
    <p><a href="http://localhost:3000/delete">削除</a></p>
    <p><a href="http://localhost:3000/insertMany">作成</a></p>
    <p><a href="http://localhost:3000/find">表示</a></p>
  </body>
</html>
  • 出来ることは、前回と変わりませんが実装はだいぶ簡略化されました。
  • find処理をしたときにJSONデータをブラウザーに表示させたい場合、findの関数を少し変更すればOKです。
  • JSON表示が潰れて見にくい場合は、JSONView 等のブラウザー拡張がありますのでつかってみるのもいいかもしれません。
app.get('/find', (req, res) => {
  console.log(req.query)
  findDocuments(db, (docs) => {
    console.log(docs)
    res.send(docs)
  })
})
  • だいぶ便利になったと思いますが、もう少しデータを増やして、任意のデータを検索できるようになると、さらに便利かもしれません。
  • 名前が momo さんのデータを取得したいとしましょう。 その場合はブラウザーのURL入力欄に、http://localhost:3000/find?name=momo と入力します。
  • そのデータは、req.query で取得できますので、コンソールログを確認してみてください。
connecting
{ name: 'momo' }
Founds the records
  • この取得したデータを、findメソッドに反映させたいと思います

  • myAppCallback


const MongoClient = require('mongodb').MongoClient
const assert = require('assert')
const express = require('express')
const app = express()

const url = 'mongodb://localhost:27017/myproject'
const dbName = 'myproject'
const client = new MongoClient(url)
const lib = require('./libCallback.js')
const { insertDocuments, insertOneDocument, findDocuments, deleteManyDocuments, findDocuments_2 } = lib


client.connect(err => {
    assert.equal(null, err)
    console.log("Connected successfully to server")
    const db = client.db(dbName)


    app.get('/', (req, res) => {
        console.log(req.query)
        res.send('hello')
    })
    app.get('/delete', (req, res) => {
        console.log(req.query)
        deleteManyDocuments(db, (result) => {
            console.log(result.result)
        })
        res.send('delete done')
    })
    app.get('/insertMany', (req, res) => {
        console.log(req.query)
        insertDocuments(db, (result) => {
            console.log(result.result)
        })
        res.send('insert done')
    })
    app.get('/find', (req, res) => {
        console.log(req.query)
        findDocuments(db, (docs) => {
            console.log(docs)
        })
        res.send('find done')
    })
    app.get('/find2', (req, res) => {
        const findsData = req.query
        console.log(req.query)
        findDocuments_2({ db, findsData },  (docs) => {

            console.log(docs)
        })
        res.send('find2 done')
    })

    app.listen(3000, () => console.log("connecting"))

})
  • libCallback.js

const assert = require('assert')

module.exports.updateOneDocument = (db, callback) => {
    const collection = db.collection('documents')
    collection.updateOne(
        { a: 1 },
        { $set: { a: 100 }}, (err, result) => {
            assert.equal(err, null)
            console.log("update the records")
            callback(result)
        })
}

module.exports.deleteManyDocuments = (db, callback) => {
    const collection = db.collection('documents')
    collection.deleteMany({}, (err, result) => {
        assert.equal(err, null)
        console.log("Delete All")
        callback(result)
    })
}

module.exports.findDocuments = (db, callback) => {
    const collection = db.collection('documents')
    collection
        .find({})
        .project({ '_id': 0})
        .toArray((err, docs) => {
            assert.equal(err, null)
            console.log("Founds the records")
            callback(docs)
        })
}

module.exports.findDocuments_2 = ({ db, findsData }, callback) => {
    const collection = db.collection('documents')
  console.log(findsData.keys())
    // const findsData = { name: 'koko'}
    collection
        .find(findsData)
        .project({ '_id': 0})
        .toArray((err, docs) => {
            assert.equal(err, null)
            console.log("Founds the records")
            callback(docs)
        })
}

module.exports.insertDocuments = (db, callback) => {
    const collection = db.collection('documents')
    collection.insertMany([
        { name: 'toto', age: 25, weight: 65, height: 176 },
        { name: 'momo', age: 27, weight: 50, height: 163 },
        { name: 'koko', age: 25, weight: 87, height: 189 },
        { name: 'nattou', age: 25, weight: 47, height: 110 },
        { name: 'hotaru', age: 25, weight: 65, height: 179 },
        { name: 'takuma', age: 55, weight: 78, height: 183 },
    ], (err, result) => {
        assert.equal(err, null)
        assert.equal(6, result.result.n)
        assert.equal(6, result.ops.length)
        console.log("Insered  documents")
        callback(result)
    })
}
  • libCallback.js に新たに findDocuments_2 を用意しました。 これを使って新たに find2へのアクセスポイントをメイン処理に追加しました。

  • ブラウザー入力欄に追加してみてください

  • totoさんだけ抽出できたかと思います。 しかし残念なことに、キーがnameの項目は抽出できますが、age, weight, height は、値のタイプが一致しないためマッチしません。

  • 少し面倒ですが、なんらかの形で type 判定が必要なようです。

  • libCallback.js

const assert = require('assert')

module.exports.updateOneDocument = (db, callback) => {
    const collection = db.collection('documents')
    collection.updateOne(
        { a: 1 },
        { $set: { a: 100 }}, (err, result) => {
            assert.equal(err, null)
            console.log("update the records")
            callback(result)
        })
}

module.exports.deleteManyDocuments = (db, callback) => {
    const collection = db.collection('documents')
    collection.deleteMany({}, (err, result) => {
        assert.equal(err, null)
        console.log("Delete All")
        callback(result)
    })
}

module.exports.findDocuments = (db, callback) => {
    const collection = db.collection('documents')
    collection
        .find({})
        .project({ '_id': 0})
        .toArray((err, docs) => {
            assert.equal(err, null)
            console.log("Founds the records")
            callback(docs)
        })
}

module.exports.findDocuments_2 = ({ db, findsData }, callback) => {
    const collection = db.collection('documents')
    const value = Object.entries(findsData)[0][1]
    const key   = Object.entries(findsData)[0][0]
    const fixFindsData = {}
    const type = fixFindsData[key] = (value - 0)
    console.log('NaN or integer: ', type)
    const input = type ? fixFindsData : findsData
    collection
        .find(input)
        .project({ '_id': 0})
        .toArray((err, docs) => {
            assert.equal(err, null)
            console.log("Founds the records")
            callback(docs)
        })
}

module.exports.insertDocuments = (db, callback) => {
    const collection = db.collection('documents')
    collection.insertMany([
        { name: 'toto', age: 25, weight: 65, height: 176 },
        { name: 'momo', age: 27, weight: 50, height: 163 },
        { name: 'koko', age: 25, weight: 87, height: 189 },
        { name: 'nattou', age: 25, weight: 47, height: 110 },
        { name: 'hotaru', age: 25, weight: 65, height: 179 },
        { name: 'takuma', age: 55, weight: 78, height: 183 },
    ], (err, result) => {
        assert.equal(err, null)
        assert.equal(6, result.result.n)
        assert.equal(6, result.ops.length)
        console.log("Insered  documents")
        callback(result)
    })
}
  • 判定部分抜き出し
const value = Object.entries(findsData)[0][1]
const key   = Object.entries(findsData)[0][0]
const fixFindsData = {}
const type = fixFindsData[key] = (value - 0)
console.log('NaN or integer: ', type)
const input = type ? fixFindsData : findsData
  • この部分で、値が数字に変換できるかチェックしています。

  • ブラウザーURL欄に, http://localhost:3000/find2?name=toto や age=25 weight=47 など いろいと入れて試して見てください

  • 今日は、ここまでにしたいと思います。 また次回も見てもらえそうなら追加改良したいと思います。 m(__)m

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@atoris1192の技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!