--- title: MongoDB tags: MongoDB --- MongoDB === ## MongoDB 教學 [[Course] MongoDB Basics](https://university.mongodb.com/courses/M001/about) ### _id * primary key primary key: 用來索引document的值,一定要是唯一(unique)的,不可以重複,且是必須存在的。 * mongodb 使用Pseudokey,刻意塞給每個document的資料,key本身對資料來說沒有任何意義,且自動生成,叫做ObjectID(),有createTime包含在裡面(可以利用getTTimestamp()從_id得到)。 ## noSQL優點 * 使用橫向擴展架構高速處理大量數據 * 存儲非結構化、半結構化或結構化數據,schema 不需要固定,且資料可以為任意結構。 * 啟用對模式和字段的輕鬆更新 * 對開發人員友好 * 利用分散式系統以及雲端儲存 ## MongoDB syntax ### switch to the specify database ``` use {DatabaseName} use myFirstDatabase ``` ### 新增collection ``` db.createCollection("{collection_name}") db.createCollection("test") ``` ### 查看Database 裡面的collections ``` show collections ``` ### insert the data in specify collection in db **If the collection did not exist, it will automatically creat a new one to insert the document** ``` db.{collection_name}.insert({document 1}) db.test.insert({"id":123456666, "user_name":"sally", "location":"Taiwan"}) ``` ### insert multiple documents by using an array ``` db.{collection_name}.insert([{document 1}, {document 2}]) db.test.insert([{"id":123456666, "user_name":"sally", "location":"Taiwan"}, {"id":7777777, "user_name":"chester", "location":"Taiwan"}]) ``` ### view collection informations in db ``` db.getCollectionInfos({name:"{collection_name}"}); db.getCollectionInfos({name:"test"}); ``` ### find the specify data fit the query ``` db.{collection_name}.find({query}) db.test.find({"id":123456666}) ``` ### get a random document from the collection ``` db.{collection_name}.findOne(); ``` ### count the number of data in collection ``` db.{collection_name}.find({query}).count() db.test.find({"user_name":"sally"}).count() ``` ### view all the documents in the collection ``` db.{collection_name}.find().pretty() db.test.find().pretty() ``` ### view the specify data in pretty way ``` db.{collection_name}.find({query}).pretty() db.test.find({"user_name":"sally"}).pretty() ``` ### update one document contexts ``` db.{collection_name}.updateOne({old_query},{"$set":{"<fields>": <new_value>}}) db.test.updateOne({"id":130123332},{"$set":{"id":6666666}}) ``` ### Update operators #### sets field value to a new sspecified value ``` "$set": { "pop": 17630 } ``` #### increments field value by a specified amount ``` "$inc": { "pop": 10 } ``` #### adds an element to an array field ``` "$push": { "scores": { "type": "extra credit", "score": 100 } } ``` ### delete the document ``` db.{collection_name}.deleteOne({"id":123456666}) db.test.deleteOne({"id":123456666}) ``` ### Delete the collection ``` db.{collection_name}.drop() db.test.drop() ``` ## Aggregation Aggregation 是幫助我們在 MongoDB server 端進行「資料處理」的工具。 利用pipeline做filter,將資料進行運算或是reshape或是reorganize,資料處理的先後順序會讓結果不同,先做一層處理之後再做下一層,以此類推。 ``` // 針對 products collection 使用 aggregate db.products.aggregate([ 找出所有「科技類」商品, // 第一個 stage 找到其中「價錢最高」的商品 // 第二個 stage ]) ``` # $ 用途 * denotes the use of an operator:當作運算符使用 * addresses the field value:表示正在尋找的變數,而不僅僅是字段名稱本身 # 邏輯運算符號 * \$eq:等於 db.inventory.find( {tags : {$eq : ['A', 'B']}} ) 也可以直接寫成:db.inventory.find( {tags : ['A', 'B']} ) * \$gt:大於 * \$gte:大於等於 * \$in:包含其中任意一個 db.inventory.find( {price : {$in : [5, 15]}} ):價格為5或15的庫存 * \$lt:小於 * \$lte:小於等於 * \$ne:不等於 db.inventory.find( {price : {$ne : 20}} ):價格不是20的庫存 * \$nin:不包含其中任意一個 db.inventory.find( {price : {$nin : [5, 15]}} ):價格不是5也不是15的庫存 # $match ``` // 針對 articles collection 使用 aggregate db.articles.aggregate( // 只有一個 $match stage 的 pipeline [ { $match : { author : "dave" } } ] ); ``` # $match搭配邏輯符號 在使用 $match 時也常搭配上邏輯符號,如 $or 、 $gt 、 $lt ,能夠更精準的描述想要的資料。 ``` db.articles.aggregate( [ { $match: { $or: [ { score: { $gt: 80, $lt: 95 } }, { views: { $gte: 1000 } } ] } }, ] ); ``` # $sort 與 $limit $sort 用來將 documents 依據指定欄位排序,$limit 則是限定 documents 的數量。 這兩個 stage 常常搭配在一起使用。 ``` db.articles.aggregate( [ // 依照分數「由高而低」排序 {"$sort": { "score": -1, }}, // 只要分數「前三高」的 document {"$limit": 3} ] ); ``` # $project $project 可以用來篩選或排除 document 已經存在的欄位、也可以用來創造出新的欄位。 我們可以用 $project 來篩選需要的兩個欄位 title、lastModified,並創造出一個新的欄位 authorName。其中的 authorName 用了字串的 $concat 方法,把 author 的 first name 跟 last name 串連起來: ``` db.books.aggregate( [ { $project: { title: true, // true 表示要留下這個欄位 lastModified: true, authorName: { // 產生一個新的欄位 authorName $concat: [ "$author.first", ' ', "$author.last" ] } } } ] ) ``` _id 這個欄位:由於 _id 是 document 的主鍵,除非「特別排除」這個欄位,否則使用 $project 時預設都會保留下來。如果想要排除 _id ,要再加上一行 _id: false. # $group $group 可以把 document 「分組」,還可以根據分組結果做數學運算。是非常好用的工具之一。 我們使用 $group 方法,計算出每一個 item 各別賣出了多少數量: * _id:要做分組的欄位。範例中我們把相同 item 的資料 group 在一組。 * totalSaleQuantity:我們新加上的欄位。透過 $sum 把相同 item 的 quantity 相加 ``` db.sales.aggregate([ { $group : { _id : "$item", // 用 item 欄位做分組 totalSaleQuantity: { $sum: "$quantity" } // 使用 $sum 把同個 item 的 quantity 相加 } } ]) ```