(4)被迫吃芒果的前端工程師 - MongoDB CRUD 之 Read

前言

前面我們已經新增了許多資料到 MongoDB 中,但我們要怎麼知道我們資料真的有新增進去呢?所以接下來我們要學習查詢的語法。

Read

雖然是寫著 Read (讀取),但本質上來講比較偏向搜尋(Query)的概念,在 MongoDB 的世界中,最基本的搜尋語法是 db.collection.find()

db.collection.find() 隨著你傳入的內容來決定要搜尋的結果,如果你什麼都不帶入的話,就會直接列出全部的東西

find

有趣的是,如果你是輸入 db.users.find({}) 也是會回傳全部資料。

對應到 SQL 語法的話 db.users.find() 則類似於 SELECT * FROM users

如果想要指定特定屬性的搜尋的話,則是傳入一個屬性與值,舉例來講我要搜尋年齡 28 歲的使用者,那就要這樣寫 db.users.find({ age: 28 })

指定搜尋

這種搜尋方式要注意一件事情,如果有多筆相同的結果,那就會全部回傳,例如搜尋年齡 25 人就會全部出現

指定搜尋

而這種搜尋方式就跟使用 WHERE 是相同的

1
SELECT * FROM users WHERE age = "28"

當然也可以帶入多個欄位條件 db.users.find({ age: 25, name: 'Roy' })

如果是只想回傳符合條件的第一筆的話,則是使用 findOne,例如:db.users.findOne({ age: 25, name: 'Roy' })

條件式查詢

那麼真實在使用資料庫上只會使用單一欄位查詢這種方式嗎?當然不可能,那為了方面稍後的練習,因此建議你輸入以下程式碼注入一些資料,以便稍後的練習

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
db.users.insertMany([
{
"name": "Clayton Jimenez",
"age": 15,
"status": false
},
{
"name": "Annie Barrett",
"age": 38,
"status": true
},
{
"name": "Monica Hale",
"age": 56,
"status": true
},
{
"name": "Monica Curtis",
"age": 35,
"status": true
},
{
"name": "Sarah Rodriquez",
"age": 22,
"status": false
},
{
"name": "Michael Austin",
"age": 29,
"status": true
},
{
"name": "Josephine Roberts",
"age": 25,
"status": true
},
{
"name": "Reginald Hall",
"age": 29,
"status": false
},
{
"name": "Letitia Fields",
"age": 14,
"status": false
},
{
"name": "Judith Ramirez",
"age": 48,
"status": true
},
])

由於條件查詢非常多,因此並不會每一個都列出來,而是只列出部分比較常見使用的部分。

那我們該如何使用 MongoDB 的條件搜尋呢?如果要加入條件的話,都要這樣寫 { <field>: { $條件運算: <value> } }

如果你不知道 field 跟 value 是什麼的話,可以看一下這張 MongoDB 架構圖

MongoDB 架構

因此讓我們接著認識一些常見的條件運算吧。

$eq

$eq 其實跟原本的條件搜尋非常像,為什麼這樣說呢?像是前面我們所練習的 db.users.find({ age: 25, name: 'Roy' }) 就等於 db.users.find({ age: { $eq: 25 } , name: { $eq: 'Roy' } })

eq

兩者語法我們可以發現並沒有差太多

1
2
3
db.users.find({ age: 25, name: 'Roy' })

db.users.find({ age: { $eq: 25 } , name: { $eq: 'Roy' } })

或許你會想說「這樣我該選擇哪一種寫法?」,以我自己來講,我會選擇 $eq 的方式撰寫就是了。

$eq 是 equals 的縮寫,也就是「等於 (=)」。

$gt

$gt 是 greater 的縮寫,也就是「大於 (>)」,舉例來講今天想要搜尋大於 18 歲以上的使用者就這樣寫

1
db.users.find({ age: { $gt: 18 } })

大於 18 歲

$gte

這時候如果你搜尋要找 25 歲跟 25 歲以上的人時,你會發現一件事情 $gt 只會列出大於 25 歲的人,等於 25 歲的人反而被忽略了

1
db.users.find({ age: { $gt: 25 } })

被忽略

最主要原因是 $gt 就是單純的大於,如果你想要找大於等於的話,那就要使用 gte,而這是 greater than or equal 的縮寫

1
db.users.find({ age: { $gte: 25 } })

大於等於

$lt

有大於當然就有小於,而小於的語法是 $lt,而 $lt 則是 less than 的縮寫。

因此你就可以試著去篩選出小於十八歲的人

1
db.users.find({ age: { $lt: 18 } })

小於 18 歲

$lte

那麼一樣 $lt 只能搜尋出小於的人,如果要找小於等於的範圍那就要使用 $lte

1
db.users.find({ age: { $lte: 18 } })

小於等於

(忘記資料中沒有 18 歲的人,但你們可以試著使用 25 歲的搜尋。)

$and

mmm…$and 的寫法其實跟多個單一條件很接近,什麼意思呢?例如我們要篩選 25 歲以上,然後狀態都是啟用的,拿一般寫法來講就可以這樣寫

1
db.users.find({ age: { $gt: 25 }, status: true })

若要使用 $and 的話則是這樣改寫

1
db.users.find({ $and: [{ age: { $gt: 25 } }, { status: true }] })

$and

$or

$or 語法就會真的滿常使用到了,例如我想要找等於 18 歲的人或者是狀態是開啟的人,那就會這樣寫

1
db.users.find({or: [{ age: { $gte: 18 } }, { status: true }]})

$or