지난 포스팅과 이어서 계속 몽고디비에 대해서 학습해보자
MongoDB에서 데이터는 JSON과 유사한 형식인 BSON(Binary JSON)을 사용해 저장된다. 예를들어 m = {ename: "smith"}
는 ename이라는 필드에 "smith"라는 문자열 값을 가지는 문서를 나타낸다. n = {empno: 1101}
는 empno 필드에 1101이라는 숫자 값을 저장한다.
db.things.save(m)
과 db.things.save(n)
은 things라는 컬렉션에 m과 n 문서를 저장한다. save()
메소드는 주어진 _id를 가진 문서가 이미 존재하면 갱신(update)하고, 존재하지 않으면 새로운 문서를 추가(insert)한다.
검색
db.things.find()
는 things 컬렉션에 있는 모든 문서를 검색합니다.
findOne()
메소드는 조건에 맞는 첫 번째 문서를 반환한다. 예를 들어, db.things.findOne({empno: 1101})
은 empno가 1101인 문서 한 개를 반환한다.
입력
db.things.insert({empno: 1102, ename: "king"})
는 새로운 문서를 things 컬렉션에 추가한다. insert()
는 주로 새 문서를 콜렉션에 추가할 때 사용된다.
갱신
db.things.update({empno: 1101}, n)
는 empno가 1101인 문서를 n 문서로 갱신한다. 갱신은 두 개의 주요 매개변수를 필요로 한다:
첫 번째는 갱신하려는 문서를 찾는 쿼리, 두 번째는 갱신할 내용이다.
$set
연산자를 사용한 갱신 예:
db.things.update({empno: 1102}, {$set: {dept: "human"}})
는 empno가 1102인 문서에 dept 필드를 추가하거나 변경한다.
삭제
db.things.remove({ename: "smith"})
는 ename이 "smith"인 모든 문서를 삭제한다.
db.things.remove({})는 things 컬렉션의 모든 문서를 삭제한다.
차이점: save, insert, update
Insert: 콜렉션에 새 문서를 추가할 때 사용된다. 문서가 존재하지 않는 경우에만 사용된다.
Update: 기존 문서의 특정 필드를 수정할 때 사용된다. $set 등의 연산자와 함께 사용하여 특정 필드만 수정할 수 있다.
Save: 문서의 _id 필드를 기준으로, 해당 _id를 가진 문서가 존재하면 전체 문서를 갱신하고, 없으면 새로운 문서를 추가한다. 필드 단위가 아닌 전체 문서 단위의 갱신이 특징이다.
JSON (JavaScript Object Notation)
{}
안에 표현되며, 키-값 쌍으로 데이터를 저장한다.BSON (Binary JSON)
따라서 MongoDB를 사용할 때 데이터는 개발자에게는 JSON형태로 보이지만 실제로는 서버 내부에서 BSON형태로 저장되고 처리된다.
ObjectId 타입
_id
필드를 갖는다. 이 필드는 ObjectId
타입을 사용하여 자동 생성된다.ObjectId
는 12바이트의 바이너리 데이터로, 생성 시간의 타임스탬프, 머신 아이디, 프로세스 아이디, 그리고 순차적인 카운터를 포함한다.ObjectId
는 각 문서의 고유성을 보장한다.Date 타입
Date
타입을 제공한다.new Date()
함수를 사용하여 현재 날짜와 시간을 생성할 수 있다.Date
객체는 .getMonth()
, .getFullYear()
등의 메소드를 사용하여 다양한 날짜 정보를 추출할 수 있다.Timestamp 타입
Timestamp
타입은 내부적으로 복제와 같은 목적으로 사용되는 특별한 타입이다.Timestamp
는 64비트 값으로, 주로 몽고DB의 내부 운영에 사용되며, 복제 프로세스에서 데이터의 버전 관리에 쓰인다.배열 데이터 타입
[]
를 사용하여 표현되며, 문서 내에서 배열 형태로 데이터를 저장할 수 있다.db.things.save({empno: 1103, ename: "test", salaries: [1000, 2000]})
.find()
로 문서를 조회 후, 반복문을 사용하여 각 요소에 접근할 수 있다.배열 데이터 저장 및 조회:
// 배열에 데이터 저장
for(var n = 1103; n <= 1120; n++) {
db.things.save({empno: n, ename: "test", sa1: 1000});
}
// 배열 데이터 출력
var cursor = db.things.find();
while(cursor.hasNext()) {
printjson(cursor.next());
}
날짜 데이터 타입 사용:
var x = new Date();
console.log(x.toISOString()); // 현재 날짜를 ISO 문자열 형태로 출력
var d = ISODate();
console.log(d.getMonth()); // 현재 월 정보 출력
타임스탬프
데이터 타입 사용:
db.foo.insert({ x : 1, y : new Timestamp() });
var result = db.foo.find({}, {_id : 0});
printjson(result.toArray());
MongoDB에서 사용하는 다양한 연산자들은 데이터를 조회하고 조작할 때 매우 유용하게 사용된다. 여기에는 비교 연산자, 불린 연산자, 산술 연산자, 그리고 문자열 연산자 등이 포함된다. 이들 각각의 연산자는 특정 조건을 충족하는 데이터를 필터링하거나, 데이터를 변형하는 데 사용된다.
비교 연산자
$lt
(less than, 미만): 첫 번째 값이 두 번째 값보다 작으면 true
를 반환한다.$lte
(less than or equal, 이하): 첫 번째 값이 두 번째 값보다 작거나 같으면 true
를 반환한다.$gt
(greater than, 초과): 첫 번째 값이 두 번째 값보다 크면 true
를 반환한다.$gte
(greater than or equal, 이상): 첫 번째 값이 두 번째 값보다 크거나 같으면 true
를 반환한다.$ne
(not equal, 같지 않음): 두 개의 값이 서로 다르면 true
를 반환한다.$eq
(equal, 같음): 두 개의 값이 동일하면 true
를 반환한다.예시:
db.collection.find({ age: { $lt: 30 } }) // 나이가 30 미만인 문서 조회
Boolean 연산자
$and
: 제공된 모든 조건이 참일 때만 참을 반환한다.$or
: 제공된 조건 중 하나라도 참이면 참을 반환한다.$not
: 지정된 조건의 반대 결과를 반환한다.예시:
db.collection.find({ $and: [{ age: { $gt: 20 } }, { age: { $lt: 30 } }] }) // 나이가 20 초과 30 미만인 문서 조회
$add
: 두 수를 더한다.$subtract
: 첫 번째 값에서 두 번째 값을 뺀다.$multiply
: 두 수를 곱한다.$divide
: 첫 번째 값을 두 번째 값으로 나눈다.$mod
: 첫 번째 값을 두 번째 값으로 나눈 나머지를 반환한다.$toUpper
: 문자열을 대문자로 변환한다.$toLower
: 문자열을 소문자로 변환한다.예시:
db.collection.aggregate([
{ $project: { upperName: { $toUpper: "$name" } } } // 이름 필드를 대문자로 변환
])
이 연산자들을 활용하면 MongoDB에서 데이터를 더 유연하고 효율적으로 다룰 수 있다. 다양한 쿼리 조합을 통해 복잡한 데이터 요구 사항을 충족시킬 수 있으며, 데이터 변형도 쉽게 수행할 수 있다.
테이블 생성 (Create Table)
CREATE TABLE members (mem_no VARCHAR(30), age NUMBER, type CHAR(1), PRIMARY KEY (mem_no));
db.createCollection("members")
명령어로 진행할 수 있으나, 대부분의 경우 컬렉션은 문서 삽입 시 자동으로 생성된다.테이블 구조 변경 (Alter Table)
ALTER TABLE members ADD regist_date DATE;
/ ALTER TABLE members DROP COLUMN regist_date;
인덱스 생성 및 삭제 (Create & Drop Index)
CREATE INDEX i_members_type ON members(type);
/ DROP INDEX i_members_type;
db.members.createIndex({type: 1});
/ db.members.dropIndex("i_members_type");
레코드 삽입 (Insert Records)
INSERT INTO members (Mem_no, Age, Type) VALUES ('T20130102', 35, 'GOLD');
db.members.insert({_id: ObjectId("..."), mem_no: 'T20130102', age: 35, type: 'GOLD'});
레코드 갱신 (Update Records)
SQL: UPDATE members SET type = 'GOLD' WHERE age > 45;
MongoDB: db.members.update({age: {$gt: 45}}, {$set: {type: 'GOLD'}}, {multi: true});
여기서 SQL에서는 UPDATE
명령어를 사용하고, MongoDB에서는 $gt
(greater than) 비교 연산자와 $set
연산자를 사용한다. {multi: true}
옵션을 추가하여 여러 문서를 업데이트한다.
SQL: UPDATE members SET age = age + 3 WHERE type = 'ACE';
MongoDB: db.members.update({type: 'ACE'}, {$inc: {age: 3}}, {multi: true});
이 경우, SQL에서는 연산자를 직접 사용하고, MongoDB에서는 $inc
(increment) 연산자를 사용하여 age 필드를 증가시킨다.
기본 조회 및 WHERE 절 사용
SELECT * FROM members WHERE mem_no LIKE '%2013%';
db.members.find({mem_no: /2013/})
LIKE
연산자는 MongoDB에서 정규 표현식을 사용한다.정렬 (Order By)
SELECT * FROM members WHERE type = 'ACE' ORDER BY mem_no ASC;
db.members.find({type: 'ACE'}).sort({mem_no: 1})
.sort({field: 1})
는 오름차순, .sort({field: -1})
는 내림차순 정렬을 의미한다.개수 조회 (Count)
SELECT COUNT(*) FROM members;
db.members.count()
또는 db.members.find().count()
.count()
메소드로 문서의 개수를 조회한다.고유 값 조회 (Distinct)
SELECT DISTINCT type FROM members;
db.members.distinct("type")
.distinct()
메소드는 주어진 필드의 모든 고유 값들을 배열로 반환한다.조건부 조회
SELECT * FROM members WHERE type = 'ACE' AND age = 49;
db.members.find({type: 'ACE', age: 49})
복합 조건 조회 (AND, OR)
SELECT * FROM members WHERE type = 'ACE' OR age = 49;
db.members.find({$or: [{type: 'ACE'}, {age: 49}]})
$or
연산자를 사용하여 여러 조건 중 하나라도 참이면 문서를 반환한다.범위 조건 조회 (Greater Than, Less Than)
SELECT * FROM members WHERE age > 45;
db.members.find({age: {$gt: 45}})
$gt
(greater than), $lt
(less than), $gte
(greater than or equal to), $lte
(less than or equal to)와 같은 연산자를 사용하여 범위 조건을 명시한다.한 개의 문서만 조회
SELECT * FROM members WHERE rownum = 1;
db.members.findOne()
.findOne()
메소드는 조건에 맞는 첫 번째 문서 하나만 반환한다.