# 第零週 - mongoDB 前置教學 # 安裝 mongodb ## 前置環境安裝 * [mongo 安裝](https://www.mongodb.com/try/download/community) * [compass 安裝](https://www.mongodb.com/try/download/compass) ## driver 介紹 1. [mongoDB 官方文件](https://docs.mongodb.com/manual/core/document/) 2. [.NET Core](https://docs.microsoft.com/zh-tw/aspnet/core/tutorials/first-mongo-app?view=aspnetcore-6.0&tabs=visual-studio) 3. [Node.js NPM Mongoose](https://mongoosejs.com/docs/api/model.html#model_Model.findOne) ## 如何開啟一個 mongo 資料庫 1. 新增 data 與 log 資料夾 2. 指行指令:`mongod --dbpath "data 資料夾"` 3. 若要有 log: `mongod --dbpath "DB資料夾路徑" --logpath "LOG資料夾路徑/mongo.log"` ``` mongo 與 mongod 指令差異 1. mongod:server 端開啟伺服器應用 2. mongo: 客戶端,直連造訪您開啟的 server 應用 ``` ## 常見指令 ## 資料庫顯示 - 顯示資料庫:show dbs - 切換資料庫:use `資料庫名稱` - 觀看指令資料庫裡面的集合:show collections ### 新增一筆資料 insertOne ```jsx db.rooms.insertOne( {name:"單人房",price:1000,rating:4.5} ) ``` ### 新增多筆資料 insertMany ```jsx db.rooms.insertMany( [ { "rating": 4.3, "price": 1500, "name": "豪華單人房" }, { "rating": 4.8, "price": 2000, "name": "雙人房" } ] ) ``` ### 尋找集合裡面的資料 db.collections.find() ``` ## 一般搜尋 - db.集合名稱(collections name).find() - 尋找對應屬性:db.collections.find({屬性名稱:屬性值}) - 模糊搜尋:db.rooms.find({"name":/雙/}) - 數值區間:db.collections.find({屬性名稱:{$lte:400}}) - 複合條件:db.collections.find({屬性名稱:{$lte:400},rating:{$gte:4.8}}) ## 常用語法 - project 保護欄位:db.rooms.find({"name":/雙/},{"_id":0}) - 搜尋陣列裡面的值:db.rooms.find({"payment":{$in:["信用卡"]}}) ``` | $eq | 等於 | | --- | --- | | $ne | 不等於 | | $gt | 大於 | | $lt | 小於 | | $gte | 大於等於 | | $lte | 小於等於 | | $in | 存在某個值 | | $nin | 不存在某個值 | 邏輯運算子:or 或 and - `$or:find({$or:[{},{}]})` ```=javascript db.rooms.find( { $and: [ {price:{$lte:1500}}, {rating:{$gte:4.5}} ] } ) ``` ## 修改 updateOne `replaceOne()`,只能替換整個文件,`updateOne()`則允許更新欄位。 ```jsx db.rooms.updateOne( {"_id":ObjectId("621edf99a20aa7506a116f9a")} ,{$set:{name:"修改雙人房"}}) ``` ### 修改多個值 [updateMany](https://docs.mongodb.com/manual/reference/method/db.collection.updateMany/)(filter 篩選 >$set 更換設定) ```jsx db.rooms.updateMany( {rating:{$gt:4.5}}, {$set:{price:300}} ) ``` ### 替換整個文檔:replaceOne、replaceMany **db.collection.replaceOne(filter, replacement, options)** ```jsx db.rooms.replaceOne( {"_id":ObjectId("621edf99a20aa7506a116f9a")}, {name:"yes~"}) ``` ### 刪除多個文件:deleteMany(filter) ```jsx db.rooms.deleteMany( { rating:{$gte:4.3} }) ``` ## 資料集 ``` =JavaScript [ { "rating": 4.5, "price": 1000, "name": "標準單人房", "payment":["信用卡","ATM"] }, { "rating": 4.3, "price": 1500, "name": "豪華單人房", "payment":["信用卡","ATM"] }, { "rating": 4.8, "price": 2000, "name": "標準雙人房", "payment":["信用卡","ATM"] }, { "rating": 4.7, "price": 2500, "name": "豪華雙人房", "payment":["ATM"] }, { "rating": 4.0, "price": 3000, "name": "標準四人房", "payment":["現金"] }, { "rating": 3.5, "price": 10000, "name": "總統套房", "payment":["現金"] } ] ``` ## 第一週主線任務範圍 1. [篩選功能:query-selectors](https://docs.mongodb.com/manual/reference/operator/query/#query-selectors) 2. [輸出結果設定:Projection Operators](https://docs.mongodb.com/manual/reference/operator/query/#projection-operators) ``` find 語法有兩個參數(parameter),分別是 Query 和 Projection,兩個非選填,如果都不設定, 1. 顯示全部:db.集合名稱(collections name).find() 2. 顯示第一個符合條件:db.collections.findOne() `db.collection.find({price:{$gt: 3000}, {title:1})` ``` 3. [Comparison](https://docs.mongodb.com/manual/reference/operator/query/#comparison):價格在 2000 以上的房子 4. [Logical](https://docs.mongodb.com/manual/reference/operator/query/#logical):[$and](https://docs.mongodb.com/manual/reference/operator/query/and/#mongodb-query-op.-and),價格在 3000(含)以下,評價在 4 分以上的房型 5. [Projection Operators](https://docs.mongodb.com/manual/reference/operator/aggregation/project/#mongodb-pipeline-pipe.-project):只顯示價格,不顯示評價 6. [Cursor Methods](https://docs.mongodb.com/manual/reference/method/js-cursor/): * limit:一頁顯示 N 筆 * skip:跳過幾筆 * count:計算總數量 * size:計算總數量,但會包含 limit、skip * pretty:程式碼簡化 ## 第一週主線任務 ### 前置作業 1. 請建立一個 database,並建立一個 `posts` collection 2. 將此 [JSON 資料](https://drive.google.com/file/d/1VCuWX2M6K-Du8pWlrcGImO_ux4Zwsa6v/view?usp=sharing),透過 Compass 倒入到 `posts` collection ``` 貼文集合欄位介紹 - name:貼文姓名 - imageUrl:貼文圖片 - content:貼文內容 - likes:按讚數 - comment:留言數 - createdAt:發文時間 - type:貼文種類[fan(粉絲)、group(社團)] - tags:貼文標籤 ``` ## 題庫 ### 課程範圍 1. 搜尋 name 欄位為 "Ray Xu" 的 document 列表 ``` =JavaScript db.posts.find({"name":"Ray Xu"}) ``` 2. 新增一筆 document,欄位皆必填 3. 新增多筆 document,欄位皆必填 4. 修改一筆 document,filter 條件請用 `_id` 指定其中一筆資料,`content` 欄位調整為`測試資料` 5. 修改多筆 `name` 欄位為 `"Ray Xu"` 的 document 列表,`content` 欄位都調整為`哈哈你看看你` 6. 刪除一筆 document,filter 條件請用 `_id` 任意指定其中一筆資料 7. 刪除多筆 document,filter 條件請用 `type` 為 `group` 的值,刪除所有社團貼文 8. 刪除多筆 document,filter 條件為以下條件 a. `name`:`Ray Xu` b. `likes`: 500(含) 個讚以下 9. 查詢全部 `post` 的 document 列表 10. 關鍵字搜尋 `name` 裡面含有 `o` 的 docuemnt 列表 11. 查詢`name` 欄位為 `"Ray Xu"` ,filter 篩選出介於 500~1000(含) 個讚 12. 查詢 `comment ` 有超過 500(含)以上的 document 列表 13. 查詢 `tag` 欄位,有 `謎因` **或(or)** `幹話` 的 docuemnt 列表 14. 查詢 `tag` 欄位,有 `幹話` 的 docuemnt 列表,需隱藏 `_id` 欄位 15. 請嘗試用 Mongo Shell 指令刪除全部 Documents ### 自主研究題 1. posts 所有 document 數量為?(回傳數字) ``` =JavaScript db.posts.find().count() ``` 2. 請查詢 `name` 為 `Ray Xu` 的 document 列表,排序為由新到舊 3. 請查詢 `name` 為 `Ray Xu` 的 document 列表,顯示前 30 筆資料 4. 請查詢 `name` 為 `Ray Xu` ,顯示100(含) 個讚以上的前 30 筆 document 列表,時間排序由新到舊 5. 請查詢 `comment` 超過 `100` 的 document 列表,跳過前 30 筆資料,再顯示 30 筆資料 6. 尋找超夯熱門貼文,請查詢 `likes` **且(and)** `comments` 都超過 `1,500(含)` 的 document 列表 7. 尋找普通熱門貼文,請查詢 `likes` **或(or)** `comments` 超過 `1,000(含)` 的 document 列表 8. 查詢 `image` 欄位為 `null` 的 document 列表 9. 隨意找一筆 document 資料,將 `tag` 欄位裡的陣列,新增一個新 tag 為 `遊記` 10. 將所有 `tag` 陣列裡的 `感情` 都移除