本篇要解決的問題
在 本機安裝好 MongoDB,也在上面建立了測試資料後,第一步最重要的,就是 CRUD(增刪查改)。
工程師最常遇到的需求,就是使用者要有的沒的資料,因此把 Read 讀取/查詢 列為系列的第二篇。
本篇主要是怎麼用命令的方式,查詢出資料庫裡的資料。
通用
列出所有 DB:
show dbs
進到指定的 collection:
use <DB名稱> use admin
清除所有 Logs:
cls
find 查詢
列出指定 collection 裡的 documents:
use <DB名稱> db.<Collection名稱>.find() use bookstore db.books.find()
MongoDB Shell 預設提供的會是前 20 筆,而不會整個 documents 全部撈出來,主要是防止遇到有幾百萬筆 documents 時,一次要全撈出來會有悲催事件發生。
如果想繼續看之後的 20 筆,輸入 it
就可以。
若想要一次撈更多的資料,突破 20 筆的限制,就用 limit(想要的筆數)
:
db.books.find().limit(30)
這樣出來的資料最多就是 30 筆,而不是預設的 20 筆。
加上條件
filter 出 collection 裡符合條件的 documents:
db.<Collection名稱>.find({ 條件 }) db.books.find({ author: "August" }) db.books.find({ author: "August", rating: 10 })
只顯示想要的字段
filter 出 collection 裡符合條件的 documents,而且只顯示指定的字段:
db.<Collection名稱>.find({ 條件 }, { 字段: 0(排除)、1(包含) }) db.books.find({ author: "August" }, { title: 1, author: 1 })
字段的數字,預設值是 0
,意思是排除這個字段,1
代表包含這個字段。
比方我們的 books 資料如下:
{ _id: ObjectId('65bba54cee4e5a09b7d87f3f'), title: "Let's Write", author: "August", pages: 500, rating: 10 }
我們寫了 { title: 1, author: 1 }
,代表查詢結果包含 title
、author
,而另外二個字段 pages
、rating
沒有寫,因此預設是 0(排除),所以最後查詢結果就是:
{ _id: ObjectId('65bba54cee4e5a09b7d87f3f'), title: "Let's Write", author: "August", }
要注意的是,除非特別指定 _id: 0
,否則 _id
字段會一直被包含在結果中。
documents 裡,只顯示想看到的字段:
db.<Collection名稱>.find({}, { 字段: 1 }) db.books.find({}, { title: 1 })
這個算是前二個的組合計,{}
代表所有 documents,{ title: 1 }
代表顯示結果只包含 title
,其它排除。
count 顯示結果筆數
count 顯示結果有幾筆:
db.<Collection名稱>.find().count() db.books.find().count()
sort 排序方式
sort 以什麼字段,由小到大或由大到小排列:
db.<Collection名稱>.find().sort({ 字段: 1(由小到大)、-1(由大到小) }) db.books.find().sort({ rating: 1 })
sort 的字段可以多個,MongoDB 會照字段的順序去排列。
比方我們寫 { rating: 1, title -1 }
,就會先照 rating 由小到大排,遇到相同的 rating,再用 title 由大到小排。
運算子 Operators
運算子都由 $
符號為開頭。
因為對 JS 比較熟,所以看到像 MongoDB 中 $gt
這種寫法有點不習慣,因此這邊會加上「類似於 JS 的 ……」來做比對,加深記憶。
大於、小於
$gt
(大於)、$gte
(大於等於)、$lt
(小於)、$lte
(小於等於)。
db.books.find({ rating: { $gt: 7 } }); # rating 大於 7 db.books.find({ rating: { $gte: 7 } }); # rating 大於等於 7 db.books.find({ rating: { $lt: 6 } }); # rating 小於 6 db.books.find({ rating: { $lte: 6 } }); # rating 小於等於 6
or、and 條件
{ $or: [{}, {}, {} ...] }
,符合其中一個條件的就可以。{ $and: [{}, {}, {} ...] }
,所有條件都要符合。
db.books.find({ $or: [ { rating: 8 }, { rating: 9 } ] }); # 類似於 JS 的:if(rating === 8 || rating === 9) db.books.find({ $and: [ { pages: { $gt: 500 }}, { pages: { $lte: 700 }} ] }) # 類似於 JS 的:if(pages > 500 && pages <= 700)
includes、not includes
$in: []
:像 JS 的 some()
,查詢出符合陣列裡任一值的。$nin: []
:像 JS 的 !some()
,查詢的結果會排除陣列裡任一值的。
db.books.find({ rating: { $in: [7,8,9] } }); # 類似於 JS 的:const result = books.some(book => [7,8,9].includes(book.rating)); db.books.find({ rating: { $nin: [1,2,3] } }); # 類似於 JS 的:const result = !books.some(book => [1,2,3].includes(book.rating));
Nested Documents 的查詢
值為陣列
假設有資料是陣列(下面的 genres
):
{ "_id": { "$oid": "65bba54cee4e5a09b7d87f3f" }, "genres": ["fantasy", "history", "comedy"] }
查找 genres
陣列裡,是否包含單一值:
db.books.find({ genres: "fantasy" })
因為範例資料是 "genres": ["fantasy", "history", "comedy"]
,包含了 fantasy
,因此結果會顯示出來。
如果只想找 genres
就只有 fanstasy
的結果,就改成:
db.books.find({ genres: ["fantasy"] })
我們的範例資料除了 fanstasy
,還有 history
、comedy
,就不符合查詢條件。
如果想查出包含 2 個以上的值,用 $all
:
db.books.find({ genres: { $all: ["fantasy", "history"] } }) # 類似於 JS 的:const result = book => ["fantasy", "history"].every(genre => book.genres.includes(genre));
我們的範例資料包含了 fantasy
、history
,因此結果會顯示出來。
Nested 資料
假設有資料是 Nested 的(下面的 reviews
):
{ "_id": { "$oid": "65bba54cee4e5a09b7d87f3f" }, "reviews": [ { "name": "August", "body": "Good" }, { "name": "Zena", "body": "Good" } ] }
查詢時,用 .
連接,比方我們要查 reviews
的 name
是 August
的:
db.books.find({ "reviews.name": "August" })
findOne
上面的 find
改成 findOne
,就會由一次最多 20 筆,改成只顯示 1 筆。

