はじめに
Python でせっせと実装していたものが、npm install
すれば、あっという間に出来てしまうことを知り、少し落ち込んだりもしたけど、Node.js で書き直している私です。Node.js は超初心者です。
開発は1人でやっていて、まだ試しに作ってるだけの状態で、Mac にあれこれ DB をたてるのが嫌なので、DB だけ docker でやっちゃおう!とやってみたところ、ちっとも繋がりませんでした。
mongoose の Top ページ (ココ)に書いてある
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true, useUnifiedTopology: true});
const Cat = mongoose.model('Cat', { name: String });
const kitty = new Cat({ name: 'Zildjian' });
kitty.save().then(() => console.log('meow'));
これのコピペが実行できないという絶望的な状況からのスタート。
動作環境
OS: MacOS Catalina Version 10.15.5 (19F101)
node: v12.18.1
mongoose: 5.9.20
MongoDB: 4.2.8
Docker: version 19.03.8, build afacb8b
docker-compose: version 1.25.5, build 8a1c60f6
docker-compose
version: "3.1"
services:
mongo:
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: user
MONGO_INITDB_ROOT_PASSWORD: secret1234
ports:
- 27017:27017
volumes:
- ./configdb:/data/configdb
- mongo_local_marketing:/data/db
mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: user
ME_CONFIG_MONGODB_ADMINPASSWORD: secret1234
volumes:
mongo_local_marketing:
driver: local
ほぼ、公式(docker hub: mongo)のまま。永続化しただけ。express はなくても良いけど、MongoDB にも不慣れで便利なのでありがたく。
で、sandbox という名前の database を作っておく。
うまくいかなかったやり方
├── app.js
└── config
└── db.js
module.exports = {
url: "mongodb://user:secret1234@0.0.0.0:27017/sandbox",
};
const mongoose = require("mongoose");
const dbConfig = require("./config/db");
// connect mongodb
mongoose
.connect(dbConfig.url, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
console.log("successfully connected to the database");
})
.catch((err) => {
console.log("error connecting to the database");
console.log(err);
process.exit();
});
実行するとエラー
$ node app.js
error connecting to the database
MongooseServerSelectionError: Authentication failed.
at NativeConnection.Connection.openUri (.../node_modules/mongoose/lib/connection.js:830:32)
at Mongoose.connect (.../node_modules/mongoose/lib/index.js:335:15)
at Object.<anonymous> (.../app.js:10:4)
at Module._compile (internal/modules/cjs/loader.js:1138:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
at Module.load (internal/modules/cjs/loader.js:986:32)
at Function.Module._load (internal/modules/cjs/loader.js:879:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47 {
reason: TopologyDescription {
type: 'Single',
setName: null,
maxSetVersion: null,
maxElectionId: null,
servers: Map { '0.0.0.0:27017' => [ServerDescription] },
stale: false,
compatible: true,
compatibilityError: null,
logicalSessionTimeoutMinutes: null,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
commonWireVersion: null
}
}
reason... ナニコレ、さっぱり分からん。認証に失敗していることだけ分かった。これ、慣れたら reason 見て理由が分かるもの?!
user/password の typo か?と思ったけど、そうじゃない。user/password の渡し方がいかんのか?と思って以下のように変更。
module.exports = {
url: "mongodb://0.0.0.0:27017/sandbox",
user: "user",
pwd: "secret1234",
};
const mongoose = require("mongoose");
const dbConfig = require("./config/db");
// connect mongodb
mongoose
.connect(dbConfig.url, {
useNewUrlParser: true,
useUnifiedTopology: true,
user: dbConfig.user,
pass: dbConfig.pwd,
})
...
ダメ。0.0.0.0
を localhost
に変えてみたり、docker-compose に書いた monogo
に変えてみたりしたけど、当然ダメ。
dbName を取ってみたら接続はできた
module.exports = {
url: "mongodb://0.0.0.0:27017",
user: "user",
pwd: "secret1234",
};
こうすると、なんか接続はできた。しかし、MongoDB 上に Database は、
- admin
- config
- local
- sandobox
の4つが存在しており、どれにつながってるのか分からん状態。Database は増やせるし。
sandbox に最初からつながりたいんですよ、私は。たまたまつながってる状態じゃなくて、ちゃんと明示した通りにつながっていて欲しいんですよ、私は。
dbName をオプションで渡す
ここを見ると、dbName もオプションで渡せるみたいなので、そのようにしてみた。
module.exports = {
url: "mongodb://0.0.0.0:27017",
user: "user",
pwd: "secret1234",
dbName: "sandbox",
};
const mongoose = require("mongoose");
const dbConfig = require("./config/db");
// connect mongodb
mongoose
.connect(dbConfig.url, {
useNewUrlParser: true,
useUnifiedTopology: true,
user: dbConfig.user,
pass: dbConfig.pwd,
dbName: dbConfig.dbName,
})
.then(() => {
console.log("successfully connected to the database");
})
.catch((err) => {
console.log("error connecting to the database");
console.log(err);
process.exit();
});
const Cat = mongoose.model("Cat", { name: String });
const kitty = new Cat({ name: "Zildjian" });
kitty.save().then(() => console.log("meow"));
実行
$ node app.js
successfully connected to the database
meow
にゃー。
"sandbox" database の "cats" collection にジルジャン入ってました。シンバルか!
{
_id: ObjectId('5ef8b261164eb0103f341ef6'),
name: 'Zildjian',
__v: 0
}
つながらなかった理由
わかりまsn笑
同じ症状の人が見当たらなかったので、私の環境のせい?今度暇な時にゆっくり mongoose のソースコードを追ってみるかも知れない。
今日はいったん、ここまで。あと MongoDB に突っ込めばいったん開発おしまいなので、そっちをやってから。