我在使用 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,开发就算告一段落了,所以先处理那边的事情吧。

广告
将在 10 秒后关闭
bannerAds