我在使用 Docker 中的 Mongoose 连接 MongoDB 时遇到了问题的经历
首先
了解了用Python辛苦实现的东西,只需要npm install一下,就可以很快完成,虽然有点失落,但我正在用Node.js重新编写它。我在Node.js方面是个超级初学者。
因為我正在獨自進行開發,並且還處於試驗性的階段,我不想在Mac上搭建各種數據庫,所以決定將數據庫單獨使用Docker處理!但很不幸的是,這個方法完全無法連接成功。
在猫鼬的顶部页面(这里)上写着
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'));
从无法执行此复制粘贴的绝望状况开始。
行动环境
操作系统:MacOS Catalina 版本 10.15.5 (19F101)
节点:v12.18.1
mongoose:5.9.20
MongoDB:4.2.8
Docker:版本 19.03.8,构建 afacb8b
docker-compose:版本 1.25.5,构建 8a1c60f6
Docker组合
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的数据库。
没成功的方法
├── 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
}
}
原因… 这是什么啊,完全搞不明白。只知道认证失败了。这个,熟悉后能看到原因吗?!我以为是用户名/密码的错误拼写?但看起来不是。是用户名/密码的传递方式有问题吗?我考虑做以下更改。
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上的数据库,
-
- admin
-
- config
-
- local
- sandobox
有四个存在,不知道连接到哪个状态。数据库是可扩展的。我想一开始就连接到沙盒,不是偶然连接而是想要按照明确指示连接。
可以通过选项传递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” 数据库的 “cats” 集合里面有一只吉尔詹。真是一个铙钹!
{
_id: ObjectId('5ef8b261164eb0103f341ef6'),
name: 'Zildjian',
__v: 0
}
无法连接的原因
我不明白,哈哈。
由于找不到有相同症状的人,是因为我的环境问题?也许下次有空的时候可以慢慢地追踪一下 Mongoose 的源代码。
今天先到这里。之后只需将数据存入 MongoDB,开发就算告一段落了,所以先处理那边的事情吧。