# MongoDB
## Install MongoDB
1. go to [MongoDB.com](https://mongodb.com)
2. Download MongoDB.tgz
3. Unarchive and rename directory from `mongodb-macos-x86_64-4.2.5` to `mongodb`
4. Move `mongodb` directory to /Users/{Username}
5. Make new directory `mongodb-data` in /Users/{Username}
6. Open terminal and type the command
```
/Users/{Username}/mongodb/bin/mongod --dbpath=/Users/{Username}/mongodb-data --fork
```
7. stop command
```
/Users/{Username}/mongodb/bin/mongod --dbpath=/Users/{Username}mongodb-data --shutdown
```
## How To Query in Terminal
### find(as select in SQL)
```mongodb
// db.collection.find(query, projection)
db.user.find({name: 'shuu'})
db.user.find({age: {$lt: 30}}) // less than
db.user.find({age: {$lte: 30}}) // less than and equal
db.user.find({age: {$eq: 30}}) // equal
db.user.find({age: {$gt: 30}}) // greater than
db.user.find({age: {$gte: 30}}) // greater than and equal
db.user.find({age: {$ne: 30}}) // not equal
db.user.find({age: 30}, {name: 1, middlename:0}) // select name, hidden middlename
// AND
db.user.find({age: {$lte: 30}, name: 'shuu'})
// OR
db.user.find(
{
$or: [
{ age: {$lte: 30} }, { name: 'shuu' }
]
}
).pretty()
```
### Insert
```mongodb
db.user.insertOne({name: 'Ronaldo', age: 34}) ## insert single document
## insertmany
db.user.insertMany([
{name: 'Messi', age: 32},
{name: 'Pirlo', age: 41}
])
```
### Update
```mongodb
db.user.update(queryCondition, updateField)
db.user.update({name: 'shuu'}, {$set: {'age': 27}})
db.user.update({age: 30}, {$set: {status: 'old'}}, {multi: true}) // 改多筆
db.user.upsert({name: 'Haaland'}, {$set: {'age': 30}}) // 如果沒有這筆資料就新建一筆
db.user.update({'user': 'Di Maria'}, {$set: {'age': 34}}, <auto_add: Boolean>, <multiple_add: Boolean>)
```
### Remove
```mongodb
db.user.remove({name: 'Pogba'})
db.user.remove((age: 30}, 1) // remove just 1
db.user.remove({}) // such as SQL truncate
```
### MongoDB writeConcern
目的是為了返回操作記錄。
```mongodb
db.user.insert({'name': 'Dybala', 'age': 27}, {writeConcern: {w: 1}})
```
上述範例為新增一個 `user`,後面的 `writeConcern` 屬性分為下列幾種:
- w: 資料寫入結點後才像 client 端確認
- `{w: 0}`: 不會傳送任何 `callback`,適用於高效啲準確性的操作
- `{w: 1}`:預設值,在資料寫入到 `primary` 後就會傳送 `callback` 給 client
- `{w: "majority"}`:資料寫入到大多數節點後才會向 client 端發送 `callback` 確認,此作法高安全性但會降低效能
- j: 資料寫入 journal 日誌之後才會通知 client 端,預設值為 false,若為 `true`,則可在當機或 rebuild 時透過 journal 來找回遺失的資料並進行恢復,但效能相對會下降。
- wtimeout:限制一個時間,防止操作被阻塞無法回應 client 端,若有設定,超出後則會回傳一個錯誤給 client
#### 參考
[**MongoDB 寫安全**](https://blog.csdn.net/robinson_0612/article/details/52913705)
## ObjectID
#### Returns a new ObjectId value. The 12-byte ObjectId value consists of:
- a 4-byte timestamp value, representing the ObjectId’s creation, measured in seconds since the Unix epoch
- a 5-byte random value
- a 3-byte incrementing counter, initialized to a random value
### Method
#### Usage
```javascript=
const { ObjectID } = require('mongodb')
const id = new ObjectID()
console.log(id) // length 24 hex string
console.log(id.getTimestamp()) // timestamp
console.log(id.id) // length 12 bytes
console.log(id.toHexString()) // length 24 hex string
```
## Use MongoDB in Node.js
```javascript=
const mongodb = require('mongodb')
const MongoClient = mongodb.MongoClient
const connectionURL = 'mongodb://127.0.0.1:27017'
const databaseName = 'task-manager'
MongoClient.connect(connectionURL, { useNewUrlParser: true }, (error, client) => {
if (error) return console.log('Unable to connect to database!!')
// get db by db name
const db = client.db(databaseName)
// insert one new data in users collection
db.collection('users').insertOne({
name: 'Shuu',
age: 27
})
})
```
## Mongo Atlas
Cloud 資料庫
https://www.mongodb.com/cloud/atlas
## Mongo Compass
Just like Robo3T, 但為了可以跟 Mongo atlas 配合,還是用 Mongo Compass 比較好。
## Robo 3T
#### Its a GUI tool for MongoDB
### Install
1. Download Robo 3T
2. Move to applications
3. Open it and create connection (just like setting SQL Pro)
###### tags: `Database` `MongoDB`