今天在 code review 修改資料腳本時,對於 $regex
查找條件覺得哪裡怪怪的,於是實際行了一下,果然找到一些貓膩。
由於 MongoDB 相關資料顯示與操作都是使用 Single quote `
或是 Double quote""
,這很容易在 $regex
查詢條件中混淆進而造成不預期的後果。
準備測試資料
1 | db.getCollection('reg-test').insertMany([ |
查詢包含 [
的資料
我們希望查詢出包含 [
的關鍵字,前後內容不拘。
於是寫出了這樣的語法 {field: { $regex: ".*\[.*", $options: "i" }}
還自以為很了解的加上了 \
來作為 [
的跳脫字元,結果得到 mongo 無情回絕!
- 解法
- 使用斜線
/
來包住 regex 語法,而非使用單/雙引號""
- 我就是要使用雙引號!也是可以,那就使用兩個反斜線
\\
作為跳脫字元
查詢包含 []
的資料
我們希望查詢出包含 []
的關鍵字,前後內容不拘。
於是寫出了這樣的語法 {field: { $regex: ".*\[\].*", $options: "i" }}
有了上面的經驗後,這次我們能夠很快解決這個問題
其中比較特殊的是,如果在 []
中間多加一個空白就能夠順利執行,但是查出的資料依舊不預期,大家可以在線上各個網站玩一下 regex 這之間差異。
查詢包含 [-]
的資料
我們希望查詢出包含 [-]
的關鍵字,前後內容不拘。
於是寫出了這樣的語法 {field: { $regex: ".*\[-\].*", $options: "i" }}
熟稔 regex 的朋友一定發現會遇到什麼問題了,是的,按照這個方法查詢,會查出兩筆資料。
第二筆資料完全不符合我們預期的包含 [-]
這種格式,其解法無他,就是上面提到的。
總結
- 使用
$regex
一率使用//
,因為這才是標準用法,且能夠避免語法錯誤 - 要使用
""
不是不行,就是要使用兩個反斜線做跳脫字元 - 更新資料前,一定要先查詢看看目標資料是否正確
- regex 少用真的會忘,規則要先弄懂