MongoDB 是知名的 NoSQL 資料庫,也是現今後端資料庫很常見的解決方案之一。而 MEAN/MERN 架構中的 M 也指的是 MongoDB, 可見其重要程度不言而喻。

p.s. MEAN (MongoDB, express.js, Angular, Node.js)

p.s. MERN (MongoDB, express.js, React, Node.js)

且隨著現代應用的演化,同時使用傳統關聯式資料庫以及 NoSQL 資料庫也十分常見,如果想體驗/練習 NoSQL 資料庫,不妨就透過 Docker 實際操作看看。

本文環境

MongoDB docker image

使用 MongoDB 的 docker image 時,會看到 MongoDB 依照 Tag 的不同分成 Simple Tags 以及 Shared Tags 2 種。

簡單說來:

  • Simple Tags 有指定作業系統以及 MongoDB 的版本,可以依照需求選擇使用
  • Shared Tags 只有指定 MongoDB 的版本, docker 會自動挑選合適的 image

以下為實際使用執行在 Ubuntu 上的 MongoDB 4.2 指令:

$ docker run -p 27017:27017 --name mongo4.2 -d mongo:4.2-bionic

執行指令之後,可使用以下指令確認 container 是否已經正常運作:

$ docker ps

成功的話,可以看到有個名稱為 mongo4.2 的 container 正在運作,並且該 container 開放 27017 通訊埠(port)可以連線(27017 為 MongoDB 預設使用的通訊埠):

CONTAINER ID   IMAGE              COMMAND                  CREATED         STATUS         PORTS                      NAMES
d7d2b2cda969   mongo:4.2-bionic   "docker-entrypoint.s…"   3 seconds ago   Up 2 seconds   0.0.0.0:27017->27017/tcp   mongo4.2

此外,值得一提的是預設的 MongoDB 並不會有任何的管理者帳號,建議可以透過以下指令,設定 MONGO_INITDB_ROOT_USERNAMEMONGO_INITDB_ROOT_PASSWORD 2 個環境變數,以讓 MongoDB 建立一組 root 管理者帳號。

$ docker run --rm -p 27017:27017 --name mongo4.2 -d mongo:4.2-bionic -e MONGO_INITDB_ROOT_USERNAME=mongoadmin -e MONGO_INITDB_ROOT_PASSWORD=secret

p.s. --rm 會刪除已存在的同名 container ,如果已存在的 container 內已有重要資料的話,請勿使用該參數

–rm Automatically remove the container when it exits

Docker 版的 MongoDB 資料儲存於何處?

使用 Docker 版的 MongoDB 時,會自動產生 2 個 volumes 供 container 內的 MongoDB 儲存資料,因此當我們重新啟動 MongoDB 的 container 後,還是可以存取先前儲存的資料。

如果要找到那些 volumes, 可以使用以下指令,取得 container Mounts 資訊:

$ docker inspect mongo4.2 | jq ".[0].Mounts"
[
  {
    "Type": "volume",
    "Name": "1881c027b2e86cb8f42ec9b6e76892dd42e645c8e13a795cbe5fdbdd56d67632",
    "Source": "/var/lib/docker/volumes/1881c027b2e86cb8f42ec9b6e76892dd42e645c8e13a795cbe5fdbdd56d67632/_data",
    "Destination": "/data/configdb",
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
  },
  {
    "Type": "volume",
    "Name": "2abd165d7988e4e9178df1cfc1a4b495d66aa7b926d892c892d6465bd0eaf0ab",
    "Source": "/var/lib/docker/volumes/2abd165d7988e4e9178df1cfc1a4b495d66aa7b926d892c892d6465bd0eaf0ab/_data",
    "Destination": "/data/db",
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
  }
]

上述結果可以看到 container 內的 /data/configdb/data/db 會對應到 Docker host /var/lib/docker/volumes/ 資料夾下的特定 volumes 。其中 /data/db 所對應的 volumes 就是實際儲存資料的地方。

也因此,如果要為 Docker 版的 MongoDB 設定不同的 volume 儲存資料的話,只要將 volume 掛載在 /data/db 此資料夾即可,例如以下指令:

$ ddocker run --rm -p 27017:27017 -v /my/datadir:/data/db
 --name mongo4.2 -d mongo:4.2-bionic

MongoDB Compass

MongoDB 運作成功之後,除了能夠用 mongo 指令連線至該 DB 進行操作之外,也可以使用具有 GUI 的工具進行連線與操作,例如 MongoDB 也提供免費的 compass 讓開發者能夠簡單地透過工具操作 MongoDB。

安裝完成後,打開該工具就可以輸入連線的設定:

mongodb://localhost

如果有設定管理帳號密碼的話,就得輸入以下形式:

mongodb://帳號:密碼@localhost

連線成功之後,會出現預設的幾個資料庫。可以按左上角的 CREATE DATABASE 新增資料庫。

本文新增 1 個名稱為 mydb 的資料庫,並在該資料庫底下新增 1 個名稱為 users 的 collection (可以想像是關聯式資料庫中的 table, 但不需要定義欄位與資料型態):

接著可以點選左側邊欄的 users 並點選 Insert Document 試著新增一組資料:

新增成功之後可以看到多了 1 組資料在 users collection 中:

p.s. _id 是由 MongoDB 自動產生的,更多關於 _id 欄位可以參考 文件

有數據之後可以試著在 filter 欄輸入搜尋條件(本文將不詳述各種 MongoDB 的語法):

p.s. 如果是搜尋自動產生的 _id 欄位,必須加上 ObjectId

截至目前為止已經是 MongoDB 基本的使用操作。

除了上述功能之外, Compass 還能夠顯示索引(index)的資訊,以及操作的 explain ,讓我們能夠了解所使用的相關操作是否有效能問題(例如查詢的欄位沒有索引導致緩慢等)。

以上,Happy Coding!

References

https://hub.docker.com/_/mongo