2021 iThome 鐵人賽 MongoDB披荊斬棘之路


DAY13 MongoDB 索引(Index) 種類與建立方式

什麼是索引(Index)

索引是資料庫設計中非常重要的一環,透過針對特定欄位(一個以上)建立索引,使得任何操作能夠快速找到資料,這也是為什麼操作的查詢條件通常都須建立索引的緣故,所以使用者情境(user scenario)對開發者來說非常重要,如果沒有這些情境,開發者無法預測這個功能該如何使用,進而無法設計出合適的結構或者索引等。

預設索引

MongoDB 內的所有 collection 都有一個 Default Index,打開任一文件都會看到一個 _id 欄位,就是這個。

_id 不需要指定,寫入資料庫時就會自動幫你產生,當然你也可以自己客製化,在某些情境很適合。

索引值排序

MongoDB 索引欄位是有排序的,預設是正序1,反序-1則需要特別設定,至於要使用哪一種排序,需要根據你的使用情境來決定。

閱讀全文 »

這篇文章主要是在讀了 提問的智慧 這篇文章後的想法,因為我很懶惰所以準備了一個我流精簡版,而精簡版可能會不盡然完全表達,請慎讀,不懂可以回去翻原文。


觀念

  1. 沒有人有義務回答你的問題
  2. 沒有得到回覆可能也是正常的,請尋求其他管道,而不是重複發文

提問前

  1. 去 Google 或論壇找前人的經驗
  2. 讀懂手冊
  3. 嘗試自己檢驗來找到答案

提問時

  1. 有禮貌
  2. 找對地方發問
  3. 切勿要求回覆到發問處以外的地方,例如(email)
  4. 不要加上對問題沒幫助的話「救命啊」「緊急」「我是新手」「抱歉我小嫩嫩」
  5. 精確的表達問題以及重現問題的步驟
  6. 附上必要資訊,例如軟體版本或是硬體規格
  7. 不要直接宣稱「我發現了BUG」或「這是個BUG」

提問後

  1. 有禮貌
  2. 更新問題結果,例如「已解決」
閱讀全文 »

2021 iThome 鐵人賽 MongoDB披荊斬棘之路


DAY12 Facet 與 Bucket 分桶統計

之前我們介紹過了 Aggregation pipeline 了,如果不太了解,請往前看 DAY10, DAY11 的文章。

Aggregate 可以經過一堆操作呈現出我們要的結果,那如果我們要的結果是有一種以上的呈現方式怎麼辦?例如一個學校想看本校學測的學生們分析資料,一個想看按分數來分群,一個想看按班級來分群,就得準備兩次查詢語法,再分別記錄下來。

當然不用這麼麻煩,這時候就是 facet 出場的時候了,facet 能夠在一次查詢內執行多個 aggregate 並回傳結果,這樣做的好處就是來源資料只需要查詢一次。兩次可能還無法看出效果,如果是十次二十次呢?輸入的資料只需做一次,就能省掉額外的消耗。

我們先來看看 Facet 的 pattern:

1
2
3
4
5
6
7
8
db.artwork.aggregate( [
{
$facet: {
"output1": [ aggregate1-stage1 , aggregate1-stage2 ],
"output2": [ aggregate2-stage1 , aggregate2-stage2 ]
}
}
])

在使用上有些原生的限制:

閱讀全文 »

2021 iThome 鐵人賽 MongoDB披荊斬棘之路

DAY11 MongoDB 深入聚合與常見問題

MongoDB 的運算子前面有提到過,那是屬於查詢用的,本篇還會再提到一些運算子,專門是給 aggregate 使用。$sort$limit在昨天講完了,今天繼續…


$project

指定取出那些欄位,例如我只想知道評價最高的電影名稱,可以只顯示 name 欄位。語法如下:

1
2
3
4
db.movie.aggregate(
{"$sort" : { "rating" : -1 }},
{"$limit" : 1},
{"$project": {"name": 1}})

結果:

1
2
3
4
5
/* 1 */
{
"_id" : ObjectId("6120c79d2976f517181ffefa"),
"name" : "movieE"
}

嗯…好像不如預期,多了 _id 欄位。其實這個欄位是預設都會查出來的,需要特別關閉它,語法也很簡單。

閱讀全文 »

2021 iThome 鐵人賽 MongoDB披荊斬棘之路

DAY10 MongoDB 聚合(Aggregate)種類介紹

終於來到第十天,進入比較有趣的聚合了,這個算是 MongoDB 裡面比較有趣(X)、痛苦(O)的開始。

大家很常使用到 RDBMS 的 group 語法,MongoDB 也是有這樣的語法,叫做 Aggregation,只要是將資料筆數縮減、或是文件變成某一種形式呈現,就是屬於 Aggregation 範圍。

MongoDB 的 Aggregation 分為兩種階段,第一種階段為 資料篩選,第二種階段為資料聚合與統計,白話來說就是一個是選擇要處理的資料,另一個是把資料整理成你想看得樣子。但要記得,這兩者間沒有順序關係,也沒有次數限制,你可以[篩選 -> 統計] 或者 [統計 -> 篩選 -> 統計] 都是可以任意安排的。

基本範例長這樣

1
2
3
4
db.employee.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$employee_id", total: { $sum: "$field" } } }
])

MongoDB Aggregation 種類

MongoDB aggregation 分為三種,後兩種都是比較有彈性、客製化,但是方法不同。

閱讀全文 »

2021 iThome 鐵人賽 MongoDB披荊斬棘之路


DAY9 MongoDB 文件與嵌入式(巢狀)文件查詢(Find)

Find

把 MongoDB 的查詢放在最後面,其實你也已經學完了,但我還是快速帶過基本的範例。

  • 查詢 field == TargetString 的文件
1
db.collection.find({"field": "TargetString"})
  • 查詢 field == str1 OR field == str2 的文件
1
db.collection.find({"field": { $in: ["str1", "str2"] }})
  • 查詢 5 <= field < 8 的文件
閱讀全文 »

2021 iThome 鐵人賽 MongoDB披荊斬棘之路


DAY8 MongoDB 批次操作(bulk wirte) 與 Operators

bulk write

bulk write 乍聽以為是批量寫入資料,想了一下好像也說得通,但是 MongoDB 包含了更多各種操作,可以在一個指令內包含 Insert, Update, Delete 等動作,所以可以做更多事情,但千萬要記得各個指令別互相打架啊….

先來看看 bulkWrite 長相:

1
2
3
4
5
6
7
8
9
10
db.collection.bulkWrite(
[ <operation 1>,
<operation 2>,
...
],
{
writeConcern : <document>,
ordered : <boolean>
}
)

我們就先來看看測試資料有什麼內容:

1
2
3
4
5
6
7
8
{ _id: ObjectId("61310798630faf5d23c909d3"), name: 'ErrorName' },
{ _id: ObjectId("61310798630faf5d23c909d4"), name: 'Arthas' },
{ _id: ObjectId("61310798630faf5d23c909d5"), name: 'Arthas' },
{
_id: ObjectId("61310798630faf5d23c909d6"),
name: 'NewThrall',
type: 'melee'
}

這次目標就來:

閱讀全文 »

2021 iThome 鐵人賽 MongoDB披荊斬棘之路


DAY7 MongoDB 資料更新(Update)

更新(update)

資料更新(Update)如同寫入或刪除一樣,都是相同 Pattern,差別是條件比較多。

1
2
db.collection.updateOne(filter, update, options)
db.collection.updateMany(filter, update, options)

兩者基本上是一樣的,相信你們看完前面的 insertOne, insertMany, deleteOne, deleteMany 都有感覺了。

filter 是過慮條件,也就是你要找到欲更新文件的條件。

options 這個是更新的設定選項,在剛開始會用不到太多項目,只有一個要特別注意,就是 upsert,通常我們會設定為 true,這也是 MongoDB 很方便的地方。顧名思義,就是當欲更新的文件如果存在時,進行 update,當找不到這比文件時,就進行 insert

UpdateOne Demo - 1

閱讀全文 »

2021 iThome 鐵人賽 MongoDB披荊斬棘之路


DAY6 MongoDB 資料新增(Insert) 與刪除(Delete)

連線

連線方法如同前面文章提到的,這邊就不再贅述了。

首先我們直接進入一個全新的資料庫資料庫 films

1
2
3
4
5
6
7
> use films
switched to db films
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
>

這邊可以看到雖然我們 use films,但只要還沒有寫入資料前,database 還不會真正建立出來,現階段不需要擔心。

Insert

建立一筆資料語法其實很簡單 db.collection.insert() 即可。

閱讀全文 »

2021 iThome 鐵人賽 MongoDB披荊斬棘之路


DAY5 資料型別與 _id

資料型別

首先要理解 MongoDB 儲存的格式 BSON,就是 Binary JSON,雖然呈現都是 JSON 格式,但儲存還是有型別之分,這就是 BSON 的優點。

BSON 型別有以下幾種,常見的就不特別說明了

  • int
  • long
  • string
  • double
  • decimal
  • bool
  • date
  • timestamp
  • array
  • null
  • binData:此欄位儲存二進制的資料(binary data)
  • objectId:MongoDB 的精髓,稍後會提到
  • object:相當於 embedded documentnested document,更白話的說就是文件內的子文件,如範例的 publisher 欄位:
1
2
3
4
5
6
7
8
9
10
{
"_id": ObjectId("612cf44a031915cb2af17374"),
"name":"Barcraft",
"publisher":
{
"companyName":"Clizzard",
"country":"Taiwan",
"city":"Taipei"
}
}
  • regex: 這型別是宣告此欄位專門用來儲存正則式
1
2
3
4
{
"_id": ObjectId("612cf44a031915cb2af17374"),
"regexField": /[1-5]/
}
閱讀全文 »