M001 MongoDB Basics 정리

Chapter1 - What is MongoDB?

  • Namespace : dbName.collectionName 형태

Chapter2 - Importing, Exporting, and Querying Data

How does MongoDB store data?

  • MongoDB는 BSON 포맷으로 데이터를 저장한다.
  • BSON은 Binary JSON으로 JSON 보다 다양한 데이터 타입을 지원하며, 저장 공간을 보다 효율적으로 사용할 수 있다.

Importing and Exporting Data

  • mongodump, mongorestore : BSON 형태로 데이터를 export, import
  • mongoexport, mongoimport : JSON 형태로 데이터를 export, import
mongodump --uri "mongodb+srv://<your username>:<your password>@<your cluster>.mongodb.net/sample_supplies"

mongoexport --uri="mongodb+srv://<your username>:<your password>@<your cluster>.mongodb.net/sample_supplies" --collection=sales --out=sales.json

mongorestore --uri "mongodb+srv://<your username>:<your password>@<your cluster>.mongodb.net/sample_supplies"  --drop dump

mongoimport --uri="mongodb+srv://<your username>:<your password>@<your cluster>.mongodb.net/sample_supplies" --drop sales.json

Data Explorer

  • Mongo Shell 설치 (Mongo 5 부터 mongo 대신 mongosh 사용)
brew install mongosh

Homebrew 에러 발생 시 (삭제 후 재설치)
homebrew-core is a shallow clone 에러 발생 시, 화면에 안내 된 명령을 실행해도 설치가 진행되지 않는 경우

  • 삭제 스크립트 실행
/bin/bash -c "$(curl -fsSL [https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh](https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh))"
  • 파일 완전 삭제
sudo rm -rf /usr/local/Homebrew
  • 설치 스크립트 실행
/bin/bash -c "$(curl -fsSL [https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh](https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh))"

출처 : https://github.com/homebrew/install#uninstall-homebrew

  • DB 접속
mongosh "mongodb+srv://<id>:<uri>/admin" --apiVersion 1

기본 명령

  • show dbs : 모든 데이터베이스 목록 조회
  • use <dbName> : 해당 db를 기본으로 사용하도록 설정
  • show collections : 현재 db에 있는 모든 collection 목록 조회
  • db.<collectionName>.find({ query }) : 현재 사용 중인 db의 collection에서 쿼리 실행
  • find().pretty() : 실행하면 쿼리 결과를 예쁘게 보여주는데, mongosh 에서는 기본으로 제공하는 듯

Chapter3 - Creating and Manipulating Documents

Inserting New Documents - insert() order

  • 중간에 에러가 발생하면 뒤의 데이터가 삽입되지 않음
  • 2번 데이터에서 중복이 발생하여 3번 데이터 삽입이 안됨
db.inspections.insert([{"_id":1, "test":1}, {"_id":1, "test":2}, {"_id":3, "test":3}])
  • 중간에 에러가 발생해도 에러 없는 데이터는 모두 삽입 됨 ( { "ordered": false } )
  • 2번 데이터 중복과 상관 없이 데이터가 삽입 됨
db.inspections.insert([{"_id":1, "test":1}, {"_id":1, "test":2}, {"_id":3, "test":3}], {"ordered":false})

Updating Documents

Update operators

  • $inc : 필드 값을 지정한 만큼 증가시킴
  • $set : 필드 값을 지정한 값으로 새롭게 할당 (필드가 없는 경우 생성)
  • $push : 배열에 요소를 추가

Chapter4 - Advanced CRUD Operations

Query Operators - Comparison

// equal
db.collection.find({"field": {"$eq": "value"}})
db.collection.find({"field": "value"})

// less than, less than or equal
db.collection.find({"field": {"$lt": number}})
db.collection.find({"field": {"$lte": number}})

// greater than, greater than or equal
db.collection.find({"field": {"$gt": number}})
db.collection.find({"field": {"$gte": number}})

Query Operators - Logic

// and
db.collection.find({"$and" : [{"field1": "value1"}, {"field2": "value2"}]})
db.collection.find({"field1": "value1", "field2": "value2"})
db.collection.find({"$and" : [{"field": {"$gt": 25}}, {"field": {"$lt": 100}}]})
db.collection.find({"field": {"$gt": 25, "$lt": 100}})

// or, nor
db.collection.find({"$or": [{"field1": "value1"}, {"field2": "value2"}]})
db.collection.find({"$nor": [{"field1": "value1"}, {"field2": "value2"}]})

// not
db.collection.find({"usertype": {"$not": {"$eq":"Subscriber"}}})
  • $and 연산자는 동일한 연산자를 두 번 이상 포함해야 할 때 사용
  • $and 연산자를 사용하지 않으면 엉뚱한 값이 나오게 됨
db.routes.find({ 
  "$and": [ 
    { "$or" :[ { "dst_airport": "KZN" }, { "src_airport": "KZN" }] },
    { "$or" :[ { "airplane": "CR2" }, { "airplane": "A81" } ] }
  ]
}) 

Expressive Query Operator

  • Document 내의 Field 끼리 비교가 필요한 경우 사용할 수 있음
{"$expr": {"$eq": ["$start station id", "$end station id"]}}

$ 는 다양한 용도로 사용 됨

  • operator를 사용할 때 (예 : $and, $or, etc...)
  • field 값의 주소를 나타낼 때 (예: “$start station id”)

Array Operators

  • 별도의 지정없이 하나의 값으로 Array Field를 검색하면, Array 안에 해당 값이 존재하는 모든 문서를 반환한다.
db.collection.find({"arrayField": "value1"})

// ["value1", "value2"]
// ["value3", "value1"]
// ["value4", "value3", "value2", "value1"]
// 이러한 문서들이 모두 반환 됨

$push

  • Array에 새로운 요소를 추가할 때 사용
  • Array이 아닌 Field를 배열로 만들 때 사용

$all

  • 순서에 상관 없이 Array에 있는 요소가 모두 동일한지 비교한다.
db.collection.find({"arrayField":{"$all":["value1", "value2", "value4", "value3"]}})

// 저장이 ["value1", "value2", "value3", "value4"]로 되어 있어도 검색 됨

$size

  • 배열의 길이를 비교
  • 범위를 지정할 수 없고, 딱 일치하는 값만 검색할 수 있음

Array Operators and Projection

projection

  • 1 : 반환하려는 Field를 지정
  • 0 : 반환하고 싶은 않은 Field를 지정
  • 0, 1 을 동시에 사용할 수 없다. 단, _id를 제외할 때에는 0을 아무 때나 사용할 수 있다.
db.collection.find({ <query> }, { <projection> })

db.collection.find({ <query> }, { <field1>: 1, <field2>: 1 })

db.collection.find({ <query> }, { <field1>: 0, <field2>: 0 })

db.collection.find({ <query> }, { <field1>: 1, "_id": 0 })

$elemMatch

  • Array 안에 있는 Sub-document의 Field를 조건으로 검색하고자 할 때
  • query 결과를 반환하지만, projection에 걸리지 않은 document는 _id만 반환한다.
db.grades.find({"class_id": 431}, {"scores":{"$elemMatch":{"score":{"$gt":85}}}})

{
  _id: ObjectId("56d5f7ec604eb380b0d8f43c"),
  scores: [ { type: 'exam', score: 93.95060569368262 } ]
},
{
  _id: ObjectId("56d5f7ec604eb380b0d8f76c"),
  scores: [ { type: 'homework', score: 93.31790089774611 } ]
},
{ _id: ObjectId("56d5f7ec604eb380b0d8f8ea") },
{ _id: ObjectId("56d5f7ec604eb380b0d8fb98") },
{ _id: ObjectId("56d5f7ec604eb380b0d8fc0c") },
{ _id: ObjectId("56d5f7ec604eb380b0d8fd69") }

Array Operators and Sub-Documents

  • . 을 이용해서 Sub-Document에 접근할 수 있음
  • Array의 경우 특정 index의 값만 검색할 수 있음

Dot notation vs elemMatch : https://techbrij.com/mongodb-query-elemmatch-dot-notation
dot notation을 이용할 경우 조건이 2개 이상이 될 경우, 하나의 element가 조건을 모두 만족하는지 체크하는 것이 아니라 하나의 조건만 맞아도 반환이 된다. 그러나 elemMatch의 경우 2개 이상의 조건이 있는 경우, 해당 조건을 모두 만족하는 element를 찾는다.

Chapter5 - Indexing and Aggregation Pipeline

Aggregation Framework

  • MQL의 모든 표현은 Aggregation Framework로 표현할 수 있다.

$group

  • _id에 그룹핑 할 Field를 지정
  • 추가 Field를 지정할 수 있음
  • $sum 을 이용해서 count를 구함
db.listingsAndReviews.aggregate([
  {"$project": {"address":1,"_id":0 }}, 
  {"$group":{ 
    "_id":"$address.country", "count":{"$sum":1}
    }
  }
]);

sort() and limit()

  • sort 없이 limit 만 사용할 경우에는 데이터의 순서를 보장 받을 수 없다.
  • 무조건 sort 후에 limit을 사용해야 한다.
  • 명령에서 limit 후에 sort를 사용한다고 해도 내부적으로는 sort가 먼저 실행 된다.

Introduction to Indexes

Single field index

db.trips.createIndex({ "birth year": 1 }) 
  • index를 생성하면, find 뿐만 아니라 sort 도 성능 향상이 된다.

Compound index

db.trips.createIndex({ "start station id": 1, "birth year": 1 })

// 아래 쿼리를 실행할 때 single field index 보다 compound index가 더 도움된다.
db.trips.find({ "start station id": 476 }).sort( { "birth year": 1 } )

Introduction to Data Modeling

Rule

  • Data is stored in the way that it is used

Upsert - Update or Insert?

db.collection.updateOne({<query>}, {<update>}, {"upsert": true})
  • 데이터가 있으면 update 없으면 insert

Chapter6 - Next Steps

좋은 웹페이지 즐겨찾기