---
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 相加
}
}
])
```