MongoDB 처음 써보기
요즘 면접 보느라 매일매일 쏘다니는 중인데
👨 : 님? MongoDB 써봄?
👽 : 아.. 아뇨..!
👨 : (왜 왔냐는 듯이) ? 아 그러시면 mongoDB 관련 질문은 안하고...
후... 또 나의 빈부분이 꿰뚫리는 것 같았다.
그럼 간단하게 CRUD 정도만 해볼까? 하며 여러 블로그를 탐색하기 시작했다.
- MongoDB 소개, 설치 및 데이터 모델링
- 몽고+고랭으로 CRUD 구현하기
- MongoDB limit( ), skip() 메서드 이용해서 페이지네이션하기
- MongoDB 스키마 디자인: one-to-N 관계
Gopher였던 내게 가장 도움이 됐던 것은 2번, 몽고+고랭으로 CRUD 구현하기 였다. 물론 특정 언어를 너무 사랑하지 말라던 그.. 유명하신 분의 말이 있긴 하지만, 학부때 C++좀 했고.. 보안 하면서 Python도 좀 했으니.. 지금은 Go를 조금 사랑해도 되지 않을까요 선생님? (근데 왜 이렇게 Java는 정이 안들까)
각설하고, MongoDB 설치부터 간단한 쿼리 정도를 다뤄보겠다.
1. 설치
는 그냥 홈페이지에서 받으세요. 설치 짱쉬움 다운로드 링크
2. RDBMS랑 MongoDB 비교
근데 다 비교하면 너무 오래걸리니까 짧게 비교함. 30초도 안걸림.
RDBMS랑 MongDB는 명칭이랑 형태가 조금 다름.
NoSQL은 대개 Key/Value 형식의 구조를 가짐. 생긴거 보자마자 JSON 생각나야함.
MongoDB도 전통적인 NoSQL이라서 Key/Value 형식의 데이터 집합임.
위에서 말하는 Document라는게 결국 {}중괄호로 둘러싸인 하나의 Key/Value인거임.
오 구조체처럼 생겼네
RDBMS
RDBMS에서 Table은 가로(라벨) 세로(속성)을 이용한 데이터 집합을 가짐.
MongoDB
근데 MongoDB는 그런거 없이, Key/Field 형식의 데이터 형식을 모아 하나의 Document가 됨. Document가 여러개 모이면 Collection이라고 함.
형태는 다른데 장단점이 있나?
어차피 MongoDB 글이니까 MongoDB 장단점만 보면,
- 수평 확장 가능한 분산 시스템
- Schema-less
- 완화된 ACID
- Open Source
RDBMS도 수평확장 가능한데 태생이 수평 확장을 지원하기 위해 만든 애들이 아니라서 좀 더 불편하다고 함. 근데 이미 30초도 지났고, 이런거 다 따지다간 데이터 저장하고 불러오는 정도로 끝내려던 글이 너무 길어질 것 같아서 여기서 뚝 끊겠음.
이 분 블로그에 글 잘 나와있음. 나머지는 여기서 보셈 (https://kciter.so/posts/about-mongodb)
3. Code Implementation
1. DB 연결
우선 DB부터 연결해야된다. MongoDB의 기본 포트는 27017이므로, 아래와 같이 입력하여 연결해준다.
func ConnectDB() (client *mongo.Client, err error) { clientOptions := options.Client().ApplyURI("mongodb://localhost:27017") client, err = mongo.Connect(context.TODO(), clientOptions) if err != nil { return nil, err } err = client.Ping(context.TODO(), nil) if err != nil { return nil, err } return }
- options.Client() : 클라이언트에 연결할 정보를 입력한다.
- mongo.Connect() : Mongo 서버에 접속하고 client를 반환한다.
- client.Ping() : 잘 연결 되었는지 확인한다.
나중엔 auth를 위해 mongo server에 id, pw도 만들어줘야 하지만 지금은 안했다.
2. Write Data
아까 Key/Value 형태로 저장해야된다고 언급했다.
그리고 구조체 처럼 생겼다는 말도 살짝 흘렸다.
이를 통해 struct를 만들고 Field만 잘 맞춰준다면 Json 패키지로 마샬, 언마샬, 인코딩, 디코딩이 가능하지 않을까? 라는 생각이 들어야 된다.
맞음. 잘 된다.
{ uuid:"dbslqjtjfdbslzmdkdlepsxlvlzpdltusdlfksmsdltkdgksanswkduf" name:"damon" age:100 address:"서울 어딘가" }
이렇게 생긴 json 파일이 있다고 하자.
이걸 Decoding하려면 아래와 같은 구조체를 만들어주면 된다.
type User struct{ UUID string `json:"uuid"` Name string `json:"name"` Age int64 `json:"age"` Address string `json:"address"` }
어쨌든 저 json 파일을 mongodb에 저장하려고한다면!
func Write(writeDB *mongo.Collection, docs User) { // 대충 공공api 비스무리한거로 json파일 받아왔다는 가정 하에 err = json.NewDecoder(resp.Body).Decode(docs) num, err := writeDB.CountDocuments(nil, bson.M{"uuid": docs[i].uuid}) if num > 0 { continue } _, err = writeDB.InsertOne(context.TODO(), docs[i]) if err != nil { return } }
- type User struct : json key/field와 동일한 구조의 구조체를 만들어준다.
- json.NewDecoder().Decode() : json파일을 구조체에 매핑한다.(디코딩)
- collection.CountDocuments() : Collection에 중복되는 uuid가 있는지 검사한다.
- collection.InsertOne() : Collection에 Document를 추가한다.
Write 쉽죠? 데이터 꺼내 쓸 때도 짱 쉽다.
3. Load Data
func Load(col *mongo.Collection, page int64) (docs []User) { findOptions := options.Find() findOptions.SetSort(bson.D{{"created_at", -1}}) findOptions.SetLimit(20) findOptions.SetSkip((page - 1) * 20) res, err := col.Find(context.Background(), bson.D{}, findOptions) if err != nil { return } err = res.All(nil, &docs) if err != nil { return } return docs }
그냥 꺼내기만 하면 좀 그러니까 옵션을 줘봤다.
- SetSort() : 생성 시간 정렬(오름차순, 내림차순)
- SetLimit() : 찾는 개수는 x개로 제한
- SetSkip() : 어느 위치부터 찾을건지 설정
그리고 실제 찾을 때는
- collection.Find(옵션들) : 데이터 찾기
- Find().ALl() : 디코딩
위와 같이 찾을 수 있었다. 솔직히 mongodb 처음 배우는 사람도 이정도는 30분이면 코딩할 수 있을거라 생각한다.
근데 왜 나는 과제 낼 때 skip 옵션 안쓰고 모든 데이터를 다 구조체로 디코딩한 다음 인덱싱했을까? 내자마자 30분이따가 바로 생각나는건 왜일까?
매일 매일 이불킥 할 거리 만들어내는 난 진짜 레전드다...
Author And Source
이 문제에 관하여(MongoDB 처음 써보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@myong/MongoDB-처음-써보기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)