1. 개요
NoSQL의 한 종류인 몽고디비(MongoDB)로 다시 돌아오겠다고 약속했던 강철지그입니다. 오늘은 저번에 만든 몽고디비에 데이터를 넣어보는 시간을 가져보려고 합니다.
2. 접속
몽고디비 서버를 실행한 뒤(mongod), 몽고 셸(mongo)을 실행하여 몽고디비에 접속합니다.
$ ./mongo MongoDB shell version: 2.4.12 connecting to: test
위 출력처럼 기본 데이터베이스인 test에 연결되면 실습을 시작할 수 있습니다.
3. 데이터 삽입
3.1 한 건 삽입하기
그리고 다짜고짜 다음과 같이 뭔가 만들어보았습니다.
> db.jeeg.insert({"city":"seoul"})
>
명령어를 조금 풀어보면, db는 현재 선택된 데이터베이스를 뜻하고, jeeg는 컬렉션 이름입니다. 즉 위 명령은 현재 데이터베이스의 jeeg 컬렉션에 {"city":"seoul"} 문서를 하나 넣는다는 의미입니다. 컬렉션이 아직 없다면 몽고디비가 필요할 때 자동으로 만들어줍니다.
성공한 것 같습니다만 혹시 몰라서 로그를 살펴봅니다.
Sat Jan 31 12:58:31.140 [initandlisten] connection accepted from 127.0.0.1:51089 #1 (1 connection now open)
Sat Jan 31 12:59:17.115 [conn1] allocating new ns file ../data/db/test.ns, filling with zeroes...
Sat Jan 31 12:59:17.147 [FileAllocator] allocating new datafile ../data/db/test.0, filling with zeroes...
Sat Jan 31 12:59:17.147 [FileAllocator] creating directory ../data/db/_tmp
Sat Jan 31 12:59:17.220 [FileAllocator] done allocating datafile ../data/db/test.0, size: 64MB, took 0.072 secs
Sat Jan 31 12:59:17.233 [FileAllocator] allocating new datafile ../data/db/test.1, filling with zeroes...
Sat Jan 31 12:59:17.233 [conn1] build index test.jeeg { _id: 1 }
Sat Jan 31 12:59:17.235 [conn1] build index done. scanned 0 total records. 0.001 secs
Sat Jan 31 12:59:17.235 [conn1] insert test.jeeg ninserted:1 keyUpdates:0 locks(micros) w:120346 120ms
Sat Jan 31 12:59:17.401 [FileAllocator] done allocating datafile ../data/db/test.1, size: 128MB, took 0.167 secs
로그를 보면 test.jeeg에 인덱스를 만들고, ninserted:1로 한 건이 삽입된 것을 확인할 수 있습니다. 나머지 파일 할당 관련 메시지는 데이터 파일을 준비하는 과정으로 보면 됩니다.
3.2 find()로 확인하기
이번에는 find()를 사용합니다.
> db.jeeg.find()
{ "_id" : ObjectId("54cc5315f9b3e67df04fc9e2"), "city" : "seoul" }
>
city가 seoul로 잘 나옵니다. 참고로 따로 지정하지 않았는데도 _id가 생겼습니다. 몽고디비는 각 문서를 구분하기 위해 기본 키 역할을 하는 _id 필드를 자동으로 만들어줍니다.
하나 더 넣어봅니다.
> db.jeeg.insert({"city":"newyork"})
> db.jeeg.find()
{ "_id" : ObjectId("54cc5315f9b3e67df04fc9e2"), "city" : "seoul" }
{ "_id" : ObjectId("54cc54ebf9b3e67df04fc9e3"), "city" : "newyork" }
>
뉴욕도 잘 들어간 것 같습니다.
3.3 여러 건 한 번에 삽입하기
그럼 이제 두 건을 동시에 insert해봅니다.
> db.jeeg.insert([{"city":"london"},{"city":"jakarta"}])
> db.jeeg.find()
{ "_id" : ObjectId("54cc5315f9b3e67df04fc9e2"), "city" : "seoul" }
{ "_id" : ObjectId("54cc54ebf9b3e67df04fc9e3"), "city" : "newyork" }
{ "_id" : ObjectId("54cc5664f9b3e67df04fc9e4"), "city" : "london" }
{ "_id" : ObjectId("54cc5664f9b3e67df04fc9e5"), "city" : "jakarta" }
잘 되고 있습니다. 배열 형태로 문서를 넘기면 여러 문서를 한 번에 넣을 수 있습니다.
3.4 _id를 직접 지정하기
그럼 이번에는 뜬금없이 _id를 직접 넣어보겠습니다.
> db.jeeg.insert({"_id":0})
> db.jeeg.find()
{ "_id" : ObjectId("54cc5315f9b3e67df04fc9e2"), "city" : "seoul" }
{ "_id" : ObjectId("54cc54ebf9b3e67df04fc9e3"), "city" : "newyork" }
{ "_id" : ObjectId("54cc5664f9b3e67df04fc9e4"), "city" : "london" }
{ "_id" : ObjectId("54cc5664f9b3e67df04fc9e5"), "city" : "jakarta" }
{ "_id" : 0 }
_id는 자동으로 만들어지기도 하지만, 위처럼 직접 지정할 수도 있습니다. 다만 같은 컬렉션 안에서 _id 값은 중복될 수 없습니다.
그리고 또 일괄 insert로, 대신 실패를 유도해 보겠습니다.
> db.jeeg.insert([{"_id":0},{"_id":1}])
E11000 duplicate key error index: test.jeeg.$_id_ dup key: { : 0.0 }
> db.jeeg.find()
{ "_id" : ObjectId("54cc5315f9b3e67df04fc9e2"), "city" : "seoul" }
{ "_id" : ObjectId("54cc54ebf9b3e67df04fc9e3"), "city" : "newyork" }
{ "_id" : ObjectId("54cc5664f9b3e67df04fc9e4"), "city" : "london" }
{ "_id" : ObjectId("54cc5664f9b3e67df04fc9e5"), "city" : "jakarta" }
{ "_id" : 0 }
duplicate key error index가 발생했고, _id:1도 삽입되지 않았습니다. 이미 _id가 0인 문서가 있기 때문에 중복 키 오류가 난 것입니다. 이 예제에서는 배열의 첫 번째 문서에서 오류가 발생했으므로 뒤에 있던 문서까지 들어가지 않은 것을 find() 결과로 확인할 수 있습니다.
정리하면, 몽고디비에서는 문서를 JSON과 비슷한 형태로 넣고, find()로 바로 확인할 수 있습니다. 또한 _id는 문서를 구분하는 중요한 값이므로 직접 지정할 때는 중복되지 않도록 주의해야 합니다.
일단 오늘은 여기까지입니다.