iT邦幫忙

2025 iThome 鐵人賽

DAY 6
0
自我挑戰組

從零開始的AI學習之路:非本科轉職的30天挑戰記系列 第 6

D6 | 學MongoDB的霧煞煞心得+基本差異整理

  • 分享至 

  • xImage
  •  

原本學SQL的時候,心想:原來這就是資料庫啊!太燒腦了吧(以前怎麼傻傻的以為Excel就夠用了)
結果後來老師說,還有NoSQL喔!那我們來下載MongoDB吧!
簡直是晴天霹靂,我的Notion筆記已經長到可以用滑鼠滾輪往下滾20下還沒結束/images/emoticon/emoticon02.gif

MongoDB...我還去查了正確發音:
Yes
真的是令我一頭霧水,特別是跟上週學的關聯式資料庫差異很大。
一開始搞不清楚哪時候該用什麼符號,整個人卡在這些神秘符號裡:
-什麼時候該用 {} 大括號?一下子大括號裡又有大括號,到底要包幾個?
-什麼時候用 [] 中括號?
-單引號''好多!
-還有$符號,到底...
-還有Add Stage?!?!pipeLine?!?!
-還有讀寫資料(甚至MP3、圖片、影片也可以)

感覺就像打開了一本魔法書,裡面全是咒語,超難懂。(應該說眼睛看懂了,腦子跟不上🥲)
https://ithelp.ithome.com.tw/upload/images/20250811/20177974IG48YHqgMh.png
接著我發現MongoDB跟Python也不太一樣,雖然文件的概念有點像Python裡的字典,但MongoDB的查詢語法還多了很多特殊符號跟操作指令。像Python的dict和list好不容易熟悉了,結果看到{ }跟[ ]在MongoDB又變成其他用法(救命)MongoDB還有$gt、$regex、$set...這種符號來下條件,燒腦了。

然後Compass的介面也需要再熟悉,偶爾也要用到shell,於是就這樣在Compass、shell、VS CODE還有我的Notion筆記之間華麗切換✨


MongoDB 常見 $ 符號整理

MongoDB 主要用 $ 符號在兩大地方:

  1. 查詢條件與更新操作的運算符
  2. 聚合管線 (Aggregation Pipeline) 階段與操作符

1. 查詢與更新常用的 $ 運算符

符號 用途說明
$eq 等於。例如:{field: {$eq: value}}
$ne 不等於
$gt 大於
$gte 大於等於
$lt 小於
$lte 小於等於
$in 欄位值在指定陣列中
$nin 欄位值不在指定陣列中
$exists 欄位是否存在,值為 truefalse
$type 欄位資料型態
$regex 正規表達式查詢
$and 多條件且
$or 多條件或
$not
$nor 多條件皆不成立
$all 陣列欄位包含所有指定值
$elemMatch 陣列欄位中符合條件的元素
$size 陣列欄位長度

更新操作符

符號 用途說明
$set 設定欄位值
$unset 移除欄位
$inc 欄位加減數值
$mul 欄位乘法
$rename 欄位重新命名
$min 將欄位值更新為指定值(只有當新值小於目前值時)
$max 將欄位值更新為指定值(只有當新值大於目前值時)
$push 陣列欄位新增元素
$pop 陣列欄位刪除第一或最後一個元素
$pull 從陣列中刪除符合條件的元素
$addToSet 將元素新增到陣列(若不存在才新增)

2. 聚合 $ 符號

管線階段 (pipeline stages)

符號 用途說明
$match 過濾文件(類似查詢)
$project 選擇輸出欄位、重塑文件
$group 分組(類似 SQL 的 GROUP BY)
$sort 排序
$limit 限制輸出筆數
$skip 跳過指定筆數
$unwind 將陣列欄位拆成多筆文件
$lookup 連接另一個 collection(左外連接)
$addFields 新增欄位
$replaceRoot 替換文件根層

聚合表達式 (aggregation expressions)

符號 用途說明
$sum 求和
$avg 平均值
$min 最小值
$max 最大值
$first 分組中第一個值
$last 分組中最後一個值
$push 將欄位值放入陣列
$addToSet 將欄位值放入陣列,避免重複
$cond 條件運算式,類似三元運算子 if-then-else
$ifNull 欄位為 null 時使用替代值
$concat 字串連接
$substr 字串截取
$toInt / $toString 型態轉換
$literal 字面值,不當作運算符處理
$dateToString 日期格式化

MongoDB Pipeline 是什麼?

MongoDB 的 pipeline 就是一串「資料處理步驟」,資料會像流水線一樣,從第一個步驟開始,經過一個接一個的處理,最後吐出你想要的結果。

每個步驟都叫做一個 stage(階段),stage 用 $ 開頭像 $match、$group、$sort 等等。每個階段都會對「文件(document)」做操作,比如:

篩選($match)
分組($group)
排序($sort)
拆解陣列($unwind)

然後下一個階段會拿前面處理完的結果繼續處理。(所以stage如果用不到就要刪掉,不然會影響到結果!)

譬如,我想買咖啡,流程是:

挑豆子(篩選出好豆) → $match
把豆子磨粉 → $project
分批包裝(分組統計) → $group
排隊出貨 → $sort

資料按照一個個stage過關,最後變成我們想要的「乾淨結果」。
一次串接多個操作,不用一個步驟一個步驟慢慢跑,可以做統計、轉換、展開陣列等比較複雜的分析!

總結

-查詢、過濾、更新常用 $ 運算符
-聚合管線階段跟表達式都用 $ 開頭
-陣列操作符特別多,推陣列、拉陣列用 $push、$pull 等


為了避免搞混,我試了這幾招:

  1. 分清「語言」與「資料結構」的界線
  • 把 Python 當作「程式語言」,MongoDB 查詢語法當成「資料庫的查詢語言」。

  • 兩者用處不同,並不是完全使用 Python 思維寫 MongoDB 查詢。

  1. 用類比幫助理解
  • 把 MongoDB 文件想像成「Python 裡的 dict,但更像一份資料清單」。

  • 把 $gt 等符號想成資料庫的關鍵字,而不是 Python 裡的函式。

  1. 多寫多試,讓手感帶動腦袋
  • 把理論放一邊,直接用 pymongo 嘗試增刪查改。

  • 遇到不懂的指令,查官方文件、看範例,邊改邊跑。

  1. 保持耐心,允許自己「一時混亂」
  • 這種思維切換一開始一定會不順,給自己時間慢慢適應。

  • 想到小時候連注音符號都認不得時,卻會背弟子規,之後就慢慢能理解意涵了/images/emoticon/emoticon07.gif

基本差異整理

操作 Python 語法 (dict/list) MongoDB 查詢語法(JSON風格) 說明
定義一筆資料 person = {"name": "厄卡倫", "age": 35, "hobbies": ["寫程式", "看動畫"]} { "name": "厄卡倫", "age": 35, "hobbies": ["寫程式", "看動畫"] } Python dict 和 MongoDB document 基本相同結構
找出年齡大於30的人 (Python自己寫過濾邏輯) db.collection.find({ "age": { "$gt": 30 } }) $gt = greater than,大於符號
找出名字是寺仁的人 (Python自己寫過濾邏輯) db.collection.find({ "name": "寺仁" }) 直接比對欄位值
新增一筆資料 people.append({"name": "小桃", "age": 25}) db.collection.insertOne({ "name": "小桃", "age": 25 }) MongoDB用 insertOne() 插入文件
更新符合條件的資料 (Python手動找資料改值) db.collection.updateOne({ "name": "小桃" }, { "$set": { "age": 26 } }) $set 更新欄位值
刪除資料 (Python用 list.remove()) db.collection.deleteOne({ "name": "小桃" }) 刪除符合條件的第一筆文件
使用陣列 hobbies = ["寫程式", "看動畫"] 文件裡的陣列同樣用[],如 "hobbies": ["寫程式", "看動畫"] MongoDB 文件可直接存陣列
查詢陣列中包含指定值的文件 (Python自己判斷list元素) db.collection.find({ "hobbies": "寫程式" }) 找出陣列欄位中含指定元素
多條件查詢 (Python自己寫複雜判斷) db.collection.find({ "age": { "$gt": 30 }, "name": "厄卡倫" }) 多個欄位條件同時符合

上一篇
D5 | 正確地下指令讓ChatGPT 更好用(還能跟我一起編故事)
下一篇
D7 | 理解 HTML 格式:網頁裡暗藏的玄機真多
系列文
從零開始的AI學習之路:非本科轉職的30天挑戰記30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言