本篇文章將介紹如何查詢 MongoDB 字串欄位的長度以及數量。
人家說上戰場,直接面對需求是最佳的進步方式,雖然不會真的陣亡,但是在時間壓力下會進步神速。
某次遇到 issue 時,需要查詢現有的某個 collection 內,x 欄位字串長度超過 y 的資料筆數有多少。不看還好,一看也沒這麼單純,因此特別記錄一下。
目標 1: 查詢 x 欄位長度超過 20 的資料有哪些
這個思路很簡單,
- 使用
strLenCP
計算出長度 - 使用
gt / eq
找出符合長度的資料 - 最外層使用
expr
來做判斷表示式
1 | db.getCollection('myctw').find({ |
上述就是查詢 myctw
這個 collection,apie.field-en
此欄位長度大於等於 30 的方式。
目標 2: 查詢目標 1 的總數量
看到目標 1 輕鬆達成,接下來我需要知道數量有多少,很自然地就在 .find()
最後加上 .count()
。
於是悲劇就發生了!
1 | "errmsg" : "$strLenCP requires a string argument, found: missing", |
我百思不得其解,應該要可以的啊?
看了一下 errmsg 不是很理解,在網路上使用這個 code 去查詢也沒得到什麼結果,於是我先縮小範圍逐個擊破,嘗試過程就不贅述了,最後得到靈感的是我當初查詢的條件是子欄位,於是我換一個欄位查看看:
1 | db.getCollection('myctw').find({ |
沒想到竟然成功了!後來確認這個錯誤的原因並不是子欄位,確實意思是:
要使用 $strLenCP 查詢,所有欄位必須是 string 且 存在
關鍵就在於後面的存在兩個字,只要有其中一筆資料不存在此欄位,就無法這樣查詢。
在這個時候我們不能忘記 Pipeline 的觀念,先過濾掉不存在此欄位的資料就沒沒問題囉!
1 | db.getCollection('myctw').find({ |
搞定收工!
解法2 Regex
其實我還寫了一個透過 regex 來計算長度的方式,此方法雖然能略過不存在欄位進行計算,但是效能比較差,我不敢放到正式環境來使用。
1 | db.getCollection('myctw').find({ |
解法3 Where
後來在網路上又看到更簡單的 $where
方式:
1 | db.getCollection('myctw').find({ |
但一樣要記得加上 $exists
過濾。
最近忙於考試的準備,就花比較少時間在 blog 上,七月後繼續開工!!