質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MongoDB

MongoDBはオープンソースのドキュメント指向データベースの1つです。高性能で、多くのリトルエンディアンシステムを利用することができます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

Q&A

解決済

2回答

428閲覧

nodejsでmongodbへの適切な接続の仕方

urakids

総合スコア21

MongoDB

MongoDBはオープンソースのドキュメント指向データベースの1つです。高性能で、多くのリトルエンディアンシステムを利用することができます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

0グッド

0クリップ

投稿2020/10/08 04:46

編集2020/10/08 06:15

前提・実現したいこと

現在node.jsの勉強中です。
あまりこういった非同期の言語を触ってこなかったので悪戦苦闘しています。

今回お聞きしたいのでnode.jsでexpressとmongoDBを使ってプログラムを組みたいのですが
メインとなるapp.jsとmongoDBを処理するmng.jsに分けたいと考えて2ファイル作りました。

最初に1ファイルで処理を書いていた際はうまくいっていたのですが
ファイルを分け、別ファンクションにしたところ、
処理がうまく通らなくなりました。
原因を調べてみたところ、mng.connectdbの中でclientが取得出来る前に
mng.get_collectionが走ってしまい、client内がnullなのでエラーが起こっておりました。
この際の適切な書き方がありましたらご教授願いたいです。

mng.connectdbの前にawaitを付けても、nodejsから違うと怒られてしまいました。。。
(await is only valid in async functionと出ます)

該当のソースコード

### app.js const express = require('express'); const app = express(); const bodyParser = require('body-parser'); require('date-utils'); const mng = require('./mng'); app.use(bodyParser.urlencoded({extended: true})); app.use(bodyParser.json()); app.get('/', (req, res) => { mng.connectdb("mongodb://localhost:27017", "nodetest"); mng.get_collection("nodetest"); mng.closedb(); res.status(200).send("ok").end(); }); const PORT = process.env.PORT || 8080; app.listen(PORT, () => { console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // その他のリクエストに対する404エラー app.use((req, res) => { res.sendStatus(404); }); module.exports = app;
### mng.js const MongoClient = require("mongodb").MongoClient; let client = null; let db = null; let cl = null; exports.connectdb = async function(url, dbName) { client = await MongoClient.connect(url, {useNewUrlParser: true, useUnifiedTopology: true}); trace("client:"+client); db = client.db(dbName); trace("db:"+db); } exports.closedb = function() { trace("closedb:"+db); if (client == null) return; client.close(); client = null; db = null; } exports.get_collection = function(collectionName) { trace("DB:"+db); if (db == null) return; cl = db.collection(collectionName); trace("Collection:"+cl); } function trace(str) { console.log(str); }

補足情報(FW/ツールのバージョンなど)

nodejs v10.16.3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

適切な接続の仕方

MongoDB の公式ページから案内されるドキュメントGetting Started)に NodeJS Edition がありますのでまずはそちらを参考にするのが良いと思います。

メインとなるapp.jsとmongoDBを処理するmng.jsに分けたいと考えて2ファイル作りました

Mongoose のようなOSSのモジュールもあり、車輪の再開発になるのではないか?と感じました。

1つのファイルに書くスタイル
Express は Router を有していますので、1つのファイルに書くスタイルをRoute毎に実践するのが分かりやすいかもしれません。

ご質問のコードに関連した (MongoDB)クライアントの閉じ方がわからない。 といった質問が挙がっていますが、その回答欄は参考になると思います。

投稿2020/10/08 21:08

AkitoshiManabe

総合スコア5432

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

urakids

2020/10/09 01:27

AkitoshiManabeさん ご返答ありがとうございます。 最初はMongoDBのドキュメントからスタートし1ファイルで作成していたのですが 勉強という事もあり、ファイルを分けてみようとして現状に至った次第です。 OSSの存在の可能性も考えたのですが、まずは勉強だし自分で書いてみるかと挑んでみた所 現状のようなドツボにハマった状態でして・・・ Routerの機能説明非常に参考になりました。 (そんな動きをしているのかと目から鱗が・・・) Mongooseを使って再挑戦してみたと思います。 ありがとうございます。
guest

0

これによると、.thenつけてますけどどうですかね??
.connect('mongodb://localhost:27017/myDB').then

http://qiita.com/one-kelvin/items/c0c036f774f0b3b98ae5

投稿2020/10/08 04:57

firegrape

総合スコア902

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

urakids

2020/10/08 05:13

firegrapeさん お返事ありがとうございます。 connectdbの部分を ``` client = await MongoClient.connect(url, {useNewUrlParser: true, useUnifiedTopology: true}).then(client => { trace("client:"+client); db = client.db(dbName); trace("db:"+db); }) ``` と変えてみたのですが、結果は同じでした。 ------------------------- DB:null closedb:null client:[object Object] db:[object Object] ------------------------- と返ってきていますので、 connectdbを呼出し後、clientやdbが取れないまま get_collectionやclosedbが呼ばれているようです。
firegrape

2020/10/08 05:19

なるほどです。 接続に時間がかかっているならsleepとか入れちゃうのはダメですか?
urakids

2020/10/08 05:24

nodejsそのものにはsleepは無いようで疑似的に実現している記事もいくつかあり試してみましたが、 全体がsleepに入ってしまい、結果としてsleepした分だけ遅い状態の同じ結果が出てしまいました。
urakids

2020/10/08 05:58

firegrapeさん何度もありがとうございます。 記事に書かれているsleepを入れるとしたら、 mng.connectdbとmng.get_collectionの間だと思うのですが 入れると SyntaxError: await is only valid in async function とシンタックスエラーが出てしまいます。 これは上記にも記載しましたmng.connectdbに入れた時も同様です。 またapp.getにasyncを付ける事も出来ません。
firegrape

2020/10/08 06:18

了解です。ふと思ったのですが、 mng.connectdb("mongodb://localhost:27017", "nodetest"); app.get('/', (req, res) => { この順番だとダメなんでしたっけ?
urakids

2020/10/08 06:34

その順番だと大丈夫だと思いますが、それだとDBをどの瞬間に閉じればいいのか判らなかったので、 get内でDBを開き、処理をして、DBを閉じるとすればいいのかと考え上記の記述に至った感じです。
firegrape

2020/10/08 06:45

なるほどです。 持論ですが、DBを閉じる処理ってそこまで重要ではないと思っていて、 むしろ、完全に処理が終わってから閉じればよいと思っています。 なので、処理がうまくいかなくなるのと引き換えにあえて、get内で connectをする必要はないかと思いました。
urakids

2020/10/08 07:02

ではclose処理はやらないという事でしょうか?
firegrape

2020/10/08 07:10

mng.connectdb("mongodb://localhost:27017", "nodetest"); app.get('/', (req, res) => { mng.get_collection("nodetest"); }); mng.closedb(); res.status(200).send("ok").end(); やってもいいですけど、せめてこの感じでどうですか?
urakids

2020/10/08 07:39

firegrapeさん。ありがとうございます。 処理的にうまく通りだしました。 ただこうやってclosedbを外に出した際、このclosedbはいつ呼ばれているのでしょうか?
urakids

2020/10/08 07:53

再度ログを付けて実行してみた所 --------------------------------- closedb:null App listening on port 8080 Press Ctrl+C to quit. client:[object Object] db:[object Object] --------------------------------- と出ていて一番最初にclosedbが実行されているようです。
firegrape

2020/10/08 07:58 編集

であれば、以下はどうですか? const PORT = process.env.PORT || 8080; app.listen(PORT, () => { console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); mng.closedb(); res.status(200).send("ok").end(); // その他のリクエストに対する404エラー app.use((req, res) => { res.sendStatus(404); }); module.exports = app;
urakids

2020/10/08 08:09

app.listenの下に書くという事ですよね? 結果は同じになりました。 また外でres.statusは書けません。(resが存在しないので)
firegrape

2020/10/08 08:25

では、初心に戻ってこれは? mng.connectdb("mongodb://localhost:27017", "nodetest"); app.get('/', (req, res) => { mng.get_collection("nodetest"); mng.closedb(); res.status(200).send("ok").end(); });
urakids

2020/10/08 09:04

この書き方ですと、一度目はうまく処理されますが、 それ以降はDBがopenしていないので処理が失敗してしまいます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問