모든 MongoDB 도큐먼트는 모든 도큐먼트가 _id
필드를 기본값으로 반드시 가지고 있어야 한다는 공통점이 있습니다.
이 _id
필드의 값은 각 도큐먼트를 구별하는 역할을 합니다.
도큐먼트 내 필드와 값이 똑같다 할지라도, _id
값이 다르면 서로 다른 도큐먼트로 간주합니다.
반면에, 도큐먼트 내 필드와 값이 다르다고 하더라도, _id
값이 같다고 하면 서로 같은 도큐먼트로 여겨 에러를 발생시킵니다.
따라서 각 도큐먼트는 고유한 _id
값을 가지고 있어야 합니다. 새로운 도큐먼트를 추가할 때, _id
값에 임의적으로 고유한 값을 생성해서 사용할 수도 있지만 보통은 ObjectId 타입(12byte, 24char)의 값으로 사용합니다.
또한 도큐먼트를 추가할 때, _id
필드와 값을 특정하지 않았다면, 자동적으로 _id
필드가 생성되고 값에 ObjectId 타입이 할당됩니다.
MongoDB에서 샘플로 제공하는 데이터를 보면 고유한 _id
가 ObjectId 타입으로 정의된 것을 확인할 수 있습니다.
데이터를 삽입하기 위해, db.컬렉션이름.insert()
명령어를 사용하여 삽입할 수 있습니다.
()
안에는 JSON 형식으로 객체를 필드 : 값 쌍
으로 넣어줍니다.
고유한 아이디 _id
를 설정하지 않으면 자동으로 ObjectId로 생성되어 삽입됩니다.
컬렉션에 이미 존재하는 값을 삽입했고, .find()
로 컬렉션에 해당하는 데이터가 존재하는지 확인할 수 있습니다.
고유한 아이디 필드를 제외하고 삽입하여 아이디를 제외한 다른 필드는 모두 같지만, 고유 아이디가 달라 삽입이 완료되었습니다.
같은 아이디로 할당하고 삽입하게되면 duplicate key error
를 확인할 수 있습니다.
.insert()
를 사용하면, 주어진 도큐먼트 배열의 인덱스 순서로 작업이 실행됩니다. 만약, duplicate key
에러가 나오는 순간, 작업은 중단 됩니다.
이런 문제를 ordered
옵션을 추가하는 것으로 삽입 순서를 바꿀 수 있습니다.
추가적으로, MongoDB는 사용자로 하여금 쉽게 새로운 컬렉션이나 데이터베이스를 생성하길 원합니다.
그래서 만약 사용자가 존재하지 않는 컬렉션에 도큐먼트를 만드는 경우, 그와 동시에 컬렉션이 만들어지게 됩니다.
db.abcd.insert({...})
만약, abcd
라는 컬렉션이 존재하지 않는데 위와 같이 명령어를 입력하면 abcd
라는 컬렉션이 만들어짐과 동시에 도큐먼트를 삽입합니다.
데이터베이스가 어떤 컬렉션을 갖고있는지 보기를 원한다면 show
명령어를 사용할 수 있습니다.
show collection
명령어는 데이터베이스 안의 컬렉션 리스트를 확인할 수 있습니다.
어떤 컬렉션의 데이터에서 원하는 필드와 값을 가진 도큐먼트를 조회하고자 한다면, .find()
로 수행할 수 있습니다.
MongoDB가 제공하는 샘플 데이터로 실습해보았습니다.
db.zips.find({"state" : "NY", "city" : "ALBANY"})
위 명령어는
zips
라는 컬렉션에서 필드 : 값
이 state : NY
인 것과, city : ALBANY
인 도큐먼트를 조회한다는 명령어입니다.
위처럼 원하는 필드와 값을 조회할 수 있습니다.
db.zips.find()
이렇게 아무 쿼리도 넣지않으면, zips
컬렉션의 모든 데이터를 조회할 수 있습니다.
db.zips.find().count()
명령어는 zips
컬렉션에 존재하는 모든 데이터의 갯수를 조회하는 명령어입니다.
db.zips.findOne()
명령어는 zips
컬렉션에 존재하는 모든 데이터 중 무작위로 데이터 1개를 가져오는 명령어입니다.
findOne()
의 괄호 안에 원하는 쿼리문을 넣으면 원하는 쿼리에 맞는 데이터를 1개 가져오게 됩니다.
mongo shell에서 도큐먼트를 업데이트 하기 위한 방법에는 updateOne
, updateMany
2가지가 있습니다.
updateOne
updateMany
미국의 우편번호 관련 데이터를 가지고 있는 zips라는 컬렉션에서 데이터를 가지고 왔습니다.
그리고 살펴보니 이 데이터에는 단순히 우편번호만 기재 되어 있는 것이 아니라, 우편 번호가 속한 도시이름, 주 이름 등이 기재되어 있고, 그 중에서도 pop이라는 필드에 해당 지역의 인구수를 기록해두었습니다.
그러나 이 데이터들은 몇 년 전의 데이터 입니다.
다시 말하면 기록되어 있는 인구수와 현재의 인구수는 일치하지 않을 수도 있습니다.
그래서 이 컬렉션의 대부분의 도시들 인구 수가 최소 10명정도 증가 했다고 가정한다면, 이때는 다수의 데이터를 업데이트 해야하기 때문에 updateMany
명령어가 적합합니다.
지역 인구 수를 업데이트 하기 위해서는 우선 updateMany 명령어를 사용합니다.
그리고 이 명령어의 첫번째 인자는 어떤 도큐먼트를 업데이트 할지 결정하는 쿼리문이 작성됩니다.
우리는 {“city”: “ALPINE”} 이라는 조건의 지역 인구수 데이터를 업데이트 할 것이기 때문에, 첫번째 인자에 {“city”: “ALPINE”} 쿼리문을 작성하였습니다.
그리고 두번째 인자는 발생할 업데이트 내용을 특정합니다.
{"$inc" : {"pop" :10}}
는 업데이트하려는 필드와 증가하는 값을 설정하는 것으로, 필드의 값을 업데이트할 수 있습니다.
$inc
는 MQL(MongoDB Query Language)의 업데이트 연산자입니다.
작업에 대한 응답을 살펴보면, matchedCount
와 modifiedCount
로 나뉘어집니다.
해당 부분은 명령어에 들어가는 쿼리문 2개에 대한 응답입니다.
matchedCount
는 첫번째 인자로 들어간 조건을 충족하는 도큐먼트의 수를 의미합니다.
여기서는 우리가 앞서 찾았던 도큐먼트의 수와 같이 9가 출력되었습니다.
그리고 modifiedCount
는 두 번째 인자로 들어간 업데이트 연산자 $inc
로 인해 수정된 도큐먼트의 수를 의미합니다.
$set
연산자를 사용하면 주어진 필드에 지정된 값을 업데이트합니다. 기존 값에 특정한 값을 증가하거나, 감소하는게 아니라 아예 지정한 값으로 재할당할 수 있습니다.
$push
연산자는 배열로 이루어진 필드의 값에 요소를 추가하기 위한 연산자입니다.
db.grades.updateOne({"student_id":250,"class_id":339},{"$push":{"scores":{"type":"extra credit","score":100}}})
위 연산자는 grades
라는 컬렉션에 student_id
가 250, class_id
가 339인 도큐먼트를 업데이트합니다.
업데이트 내용은 score
이라는 필드의 값이 배열로 이루어져 있는데, 이 배열에 새로운 type
과 score
를 추가하는 것입니다. 위와 같이 작성하는 것으로 업데이트할 수 있습니다.
deleteOne
deleteMany
mongo shell을 사용하여 도큐먼트 및 컬렉션을 삭제하려고 한다면, deleteOne( )
과 deleteMany( )
를 사용할 수 있습니다.
기본적으로 앞서 배웠던 updateOne( )
과 updateMany( )
와 작동방식은 비슷합니다.
deleteOne( )
을 사용하는 경우, _id
값으로 쿼리해 온 도큐먼트를 삭제하는 것이 좋은 접근법입니다. 우리가 만약 _id
값으로 쿼리를 하지 않는다면, 검색 쿼리문에 다양한 도큐먼트가 적합할 수 있기 때문입니다.
기준을 충족하는 도큐먼트가 많을 경우에는 deleteMany를
사용하여 다수의 도큐먼트를 삭제할 수도 있습니다.
컬렉션을 삭제하기 위해서는 drop
이라는 명령어를 사용해야 합니다.
drop
은 가져오기(importing)을 할 때에도 기존의 컬렉션과 가져오는 데이터 사이의 duplicate key
에러를 방지하기 위해서 사용하기도 했었습니다.
db.컬렉션이름.drop()
으로 삭제할 수 있습니다.