MongoDB CLI

MongoDB Shell(mongosh)常用指令參考。

Docker 環境

啟動容器

docker run -d --name testMongoDB \
  -e MONGO_INITDB_ROOT_USERNAME=admin \
  -e MONGO_INITDB_ROOT_PASSWORD=password \
  -p 27017:27017 \
  mongo

帶 Volume 掛載:

docker run -d --name mongodb \
  -p 27017:27017 \
  -v "D:/DatabaseMount/Mongo":/data/db \
  -e MONGO_INITDB_ROOT_USERNAME=admin \
  -e MONGO_INITDB_ROOT_PASSWORD=admin \
  mongo:latest

進入容器

docker exec -it CONTAINER_ID bash
mongosh

基本操作

資料庫操作

# 列出所有資料庫
show dbs

# 切換/建立資料庫(資料庫不存在時,插入資料後自動建立)
use database

# 刪除目前資料庫
db.dropDatabase()

Collection 操作

# 列出所有 collections
show collections

# 建立 collection
db.createCollection("students")

認證

db.auth("admin", "password")

查看說明

db.help()

使用者管理

createUser

db.createUser({
  user: "admin",
  pwd: "password",
  roles: [
    { role: "userAdminAnyDatabase", db: "admin" },
    "readWriteAnyDatabase"
  ]
})

建立特定資料庫使用者:

db.createUser({
  user: "user1",
  pwd: "123456",
  roles: [{ role: "readWrite", db: "demo" }]
})

grantRolesToUser

db.grantRolesToUser(
  "demouser",
  [{ role: "readWrite", db: "demo" }]
)

CRUD 操作

Create

insertOne

若 collection 不存在,MongoDB 會自動建立:

db.students.insertOne({ name: "Spongebob", age: 30, gpa: 3.2 })

輸出:

{
  "acknowledged": true,
  "insertedId": ObjectId("64fc64cd3d53295f6abd2856")
}

insertMany

db.students.insertMany([
  { name: "Patrick", age: 38, gpa: 1.5 },
  { name: "Sandy", age: 27, gpa: 4.0 },
  { name: "Gary", age: 18, gpa: 2.5 }
])

Read

find

查詢所有文件:

db.students.find()

條件查詢:

db.students.find({ age: 18 })

Projection(欄位投影)

# 只回傳 name 欄位(含 _id)
db.students.find({}, { name: true })

# 不含 _id
db.students.find({}, { _id: false, name: true })

count / limit / sort

# 計數
db.students.find().count()

# 限制筆數
db.students.find().limit(2)

# 排序(1: 升冪, -1: 降冪)
db.students.find().sort({ name: 1 })

Update

updateOne

db.students.updateOne(filter, update)

$set 運算子:欄位不存在時新增,存在時更新

db.students.updateOne(
  { name: "Spongebob" },
  { $set: { fullTime: true } }
)

使用 _id 更安全:

db.students.updateOne(
  { _id: ObjectId("65000e5f94ba2fcc6d4f05df") },
  { $set: { fullTime: false } }
)

$unset 運算子:移除欄位

db.students.updateOne(
  { name: "Sandy" },
  { $unset: { fullTime: "" } }
)

updateMany

# 為所有文件新增 fullTime 欄位
db.students.updateMany({}, { $set: { fullTime: false } })

# 僅更新沒有 fullTime 欄位的文件
db.students.updateMany(
  { fullTime: { $exists: false } },
  { $set: { fullTime: true } }
)

update(舊式語法)

db.system.users.update(
  { "user": "user1" },
  { $set: { "user": "admin" } }
)

查詢運算子

比較運算子

運算子說明
$gt大於
$gte大於等於
$lt小於
$lte小於等於
$eq等於
$ne不等於
$in在指定陣列中
$nin不在指定陣列中

範例

$gt(大於)

db.books.find({ rating: { $gt: 7 } })

$lt(小於)

db.books.find({ rating: { $lt: 8 } })

$lte(小於等於)

db.books.find({ rating: { $lte: 8 } })

邏輯運算子

運算子說明
$or
$and
$not
$nor都不是

$or 範例

db.books.find({ $or: [{ rating: 7 }, { rating: 9 }] })

組合條件:

db.books.find({
  $or: [
    { pages: { $lt: 300 } },
    { pages: { $gt: 400 } }
  ]
})

$in / $nin

# rating 在 7, 8, 9 之中
db.books.find({ rating: { $in: [7, 8, 9] } })

# rating 不在 7, 8, 9 之中
db.books.find({ rating: { $nin: [7, 8, 9] } })

其他運算子

運算子說明
$exists欄位是否存在
$set設定欄位值
$unset移除欄位

陣列查詢

包含特定值

# genres 陣列包含 "fantasy"
db.books.find({ genres: "fantasy" })

完全匹配陣列

# genres 陣列「只有」["fantasy"]
db.books.find({ genres: ["fantasy"] })

# genres 陣列為 ["fantasy", "magic"](順序需一致)
db.books.find({ genres: ["fantasy", "magic"] })

$all(包含所有指定元素)

# genres 包含 "fantasy" 和 "sci-fi"(順序無關)
db.books.find({ genres: { $all: ["fantasy", "sci-fi"] } })

查詢巢狀物件陣列

# reviews 陣列中有 name 為 "Luigi" 的物件
db.books.find({ "reviews.name": "Luigi" })

Replica Set

初始化

rs.initiate({
  _id: "rs0",
  members: [{ _id: 0, host: "localhost:27017" }]
})

查看狀態

rs.status()

輸出範例(部分):

{
  "set": "rs0",
  "myState": 1,
  "members": [
    {
      "_id": 0,
      "name": "localhost:27017",
      "health": 1,
      "state": 1,
      "stateStr": "PRIMARY"
    }
  ],
  "ok": 1
}

Aggregation Pipeline

聚合管線用於進行複雜的資料分析與轉換。

常用階段

階段說明
$match過濾文件(類似 find)
$group分組與聚合計算
$sort排序
$limit限制筆數
$lookup關聯查詢(類似 SQL JOIN)
$project欄位投影
$unwind展開陣列

$match

db.order.aggregate([
  { $match: { _id: ObjectId("5968d724592e0a4141ea43e7") } }
])

$lookup(關聯查詢)

$lookup 概念上類似 SQL 的 JOIN 操作

db.order.aggregate([
  { $match: { _id: ObjectId("5968d724592e0a4141ea43e7") } },
  {
    $lookup: {
      from: "web",
      localField: "webId",
      foreignField: "_id",
      as: "webData"
    }
  }
])

$group

計算所有使用者的平均年齡:

db.users.aggregate([
  {
    $group: {
      _id: null,
      averageAge: { $avg: "$age" }
    }
  }
])

依性別分組計算平均年齡:

db.users.aggregate([
  {
    $group: {
      _id: "$gender",
      averageAge: { $avg: "$age" }
    }
  }
])

組合範例:Top 5 最受歡迎的水果

db.users.aggregate([
  {
    $group: {
      _id: "$favoriteFruit",
      count: { $sum: 1 }
    }
  },
  { $sort: { count: -1 } },
  { $limit: 5 }
])

聚合運算子

運算子說明
$sum加總
$avg平均值
$min最小值
$max最大值
$first第一個值
$last最後一個值
$push將值加入陣列
$addToSet將不重複的值加入陣列

相關主題