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]/
}
閱讀全文 »

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


DAY4 MongoDB 資料庫與 Collection

Database

MongoDB 一個 instance 中可以有很多資料庫,預設的有三個,admin, config, local。當我們連進 MongoDB 後,輸入 show dbs 就可以看到這三個,這三個分別有其用處。

  • admin:
    看這個名字可以想見這個資料庫很重要,對的,所有的重要資訊、重要指令都只能在這個資料庫底下操作。例如要新增角色或者關閉 instance,相當於所有資料庫的 administrator 一般。

    如果要建立個別資料庫的使用者或角色,在各別的資料庫建立即可,但如果想要跨資料庫,則需要在這裡建立,這樣會自動繼承到其他資料庫。

  • config:
    此資料庫主要是存放 sharding 相關的資訊。在 3.6 版後,開始存放 standalone 或 replication 的資料,也有跟 transaction 相關的資料,但無論如何是禁止去針對這個資料庫進行修改或刪除的,僅有查看可以。

  • local:
    用來存放這個 instance,在這台機器的檔案與資訊,不會因為 replica set 的設定而把相關資料複製走,簡單來說就是別人用不到的資訊。連進去就有一個 startup_log 可以查看。

建立資料庫

建立資料庫並不需要特別宣告,直接 use 即可,以下為範例:

1
2
3
4
5
6
test> show dbs
admin 41 kB
config 111 kB
local 73.7 kB
test> use testUsedDatabase
switched to db testUsedDatabase

直接使用 use testUsedDatabase 就會切換到當下資料庫。

閱讀全文 »

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


DAY3 MongoDB 連線與 IDE

MongoDB 的連線方式主要有三種,分別是:

  • legacy mongo shell
  • mongo shell
  • IDE

學習以及開發階段,我會比較推薦使用 legacy mongo shell 搭配 IDE 的方式,不過這只是建議並非絕對。主要是 mongo shell 固然強大,但需要額外下載才能使用,一旦遇上沒有 mongo shell 的環境,在反應上可能會略差一點,尤其是線上產品的支援環境不見得會有,有的話那就萬幸了。

legacy mongo shell

這邊說的 legacy mongo shell 執行檔就是 5.0 之前的版本,也就是安裝好 MongoDB 內建的版本。會推薦的原因是少了 intellisense (是缺點也是優點),因此使用上會對指令記憶度最高,且不受環境影響,有安裝 MongoDB 的,肯定也會有這套。

如果使用 docker,那還真的是本機不見得會有呢(馬上打臉上面),解決方案就是連進 container 使用,docker exec -it mongo bash,還是有 mongo 可以使用的啦!

連線方法

閱讀全文 »