MongoDB中regex用法

好程式設計師發表於2020-12-02

   好程式設計師大資料培訓分享MongoDB regex 用法 Part1: 寫在最前

   使用MySQL 或其他關係型資料庫的朋友們都知道,使用模糊查詢的用法類似於:

   SELECT*FROMproductsWHEREskulike"%789";

   本文中介紹的MongoDB 中的 regex 就是實現類似功能的, regex 為能使你在查詢中使用正規表示式。本文會用簡單的例項帶您瞭解 MongoDB regex 的用法 ~

 

Part2: 用法

 

使用$regex 時,有以下幾種用法:

 

{<field>:{$regex:/pattern/,$options:'<options>'}}

 

{<field>:{$regex:'pattern',$options:'<options>'}}

 

{<field>:{$regex:/pattern/<options>}}

 

option 引數的含義:

 

選項含義使用要求

 

i 大小寫不敏感

 

m

 

查詢匹配中使用了錨,例如^ (代表開頭)和 $ (代表結尾),以及匹配 \n 後的字串

 

x

 

忽視所有空白字元

 

要求$regex $option 合用

 

s 允許點字元( . )匹配所有的字元,包括換行符。要求 $regex $option 合用

 

實戰

 

Part1:$in 中的用法

 

要在$in 查詢中包含正規表示式,只能使用 JavaScript 正規表示式物件(即 /pattern/ )。例如:

 

{name:{$in:[/^acme/i,/^ack/]}}

 

Warning: 警告 $in 中不能使用 $regex 運算子表示式。

 

Part2: 隱式 and 用法

 

要在逗號分隔的查詢條件中包含正規表示式,請使用$regex 運算子。例如:

 

{name:{$regex:/acme.*corp/i,$nin:['acmeblahcorp']}}

 

{name:{$regex:/acme.*corp/,$options:'i',$nin:['acmeblahcorp']}}

 

{name:{$regex:'acme.*corp',$options:'i',$nin:['acmeblahcorp']}}

 

Part3:x s 選項

 

要使用x 選項或 s 選項,要求 $regex $option 合用。例如,要指定 i s 選項,必須使用 $options 來執行以下操作:

 

{name:{$regex:/acme.*corp/,$options:"si"}}

 

{name:{$regex:'acme.*corp',$options:"si"}}

 

Part4: 索引的使用

 

對於區分大小寫的正規表示式查詢,如果欄位存在索引,則MongoDB 將正規表示式與索引中的值進行匹配,這比全表掃描更快。如果正規表示式是“字首表示式”,那麼可以最佳化查詢速度,且查詢結果都會以相同的字串開頭。

 

正規表示式也要符合“最左字首原則”,例如,正規表示式 /^abc.*/ 將透過僅匹配以 abc 開頭的索引值來進行最佳化。

 

Warning: 警告

 

1. 雖然 /^a/ /^a.*/ /^a.*$/ 匹配等效字串,但它們的效能是不一樣的。如果有對應的索引,所有這些表示式就都使用索引 ; 不過, /^a.*/ /^a.*$/ 較慢。這是因為 /^a/ 可以在匹配字首後停止掃描。

 

2. 不區分大小寫的正規表示式查詢通常不能使用索引, $regex 無法使用不區分大小寫的索引。

 

Part5: 例項

 

一個商品的集合中,存了以下內容

 

{"_id":100,"sku":"abc123","description":"Singlelinedescription."}

 

{"_id":101,"sku":"abc789","description":"Firstline\nSecondline"}

 

{"_id":102,"sku":"xyz456","description":"Manyspacesbeforeline"}

 

{"_id":103,"sku":"xyz789","description":"Multiple\nlinedescription"}

 

如果想對該商品products 集合執行一個查詢,範圍是 sku 列中的內容是 789 結尾的:

 

db.products.find({sku:{$regex:/789$/}})

 

結合MySQL 理解的話,上述查詢在 MySQL 中是這樣的 SQL:

 

SELECT*FROMproductsWHEREskulike"%789";

 

如果想查詢sku abc ABC 開頭的,且匹配時忽略大小寫,可以使用 i 選項:

 

db.products.find({sku:{$regex:/^ABC/i}})

 

查詢結果為:

 

{"_id":100,"sku":"abc123","description":"Singlelinedescription."}

 

{"_id":101,"sku":"abc789","description":"Firstline\nSecondline"}

 

Part6:m 的使用

 

想查詢描述中是包含S 開頭的,且要匹配 /n 後的 S 開頭的,則需要加 m 選項

 

db.products.find({description:{$regex:/^S/,$options:'m'}})

 

返回的結果是:

 

{"_id":100,"sku":"abc123","description":"Singlelinedescription."}

 

{"_id":101,"sku":"abc789","description":"Firstline\nSecondline"}

 

如果不加m 選項的話,返回的結果是這樣的:

 

{"_id":100,"sku":"abc123","description":"Singlelinedescription."}

 

如果不使用^ 這類錨的話,那麼會返回全部結果:

 

db.products.find({description:{$regex:/S/}})

 

{"_id":100,"sku":"abc123","description":"Singlelinedescription."}

 

{"_id":101,"sku":"abc789","description":"Firstline\nSecondline"}

 

Part7:s 的使用

 

使用s 選項來執行查詢,則會讓逗號 . 匹配所有字元,包括換行符,下文查詢了 description 列中 m 開頭,且後面包含 line 字串的結果:

 

db.products.find({description:{$regex:/m.*line/,$options:'si'}})

 

{"_id":102,"sku":"xyz456","description":"Manyspacesbeforeline"}

 

{"_id":103,"sku":"xyz789","description":"Multiple\nlinedescription"}

 

如果不包含s ,則會返回:

 

{"_id":102,"sku":"xyz456","description":"Manyspacesbeforeline"}

 

Part8:x 的使用

 

以下示例使用x 選項忽略空格和註釋,用#表示註釋,並以匹配模式中的 \n 結尾:

 

varpattern="abc#categorycode\n123#itemnumber"

 

db.products.find({sku:{$regex:pattern,$options:"x"}})

 

查詢的結果是:

 

{"_id":100,"sku":"abc123","description":"Singlelinedescription."}

 

可以看出,其忽略了abc #category 的空格以及 #category code 的空格,實際執行的查詢是 sku abc123 的結果。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913864/viewspace-2738860/,如需轉載,請註明出處,否則將追究法律責任。

相關文章