디비 확인
show dbs
컬렉션 확인
show collections
데이터 생성
db.movies.insertOne({"title" : "Stand by Me"})
데이터 확인
db.moives.find()
컬렉션 삭제
db.movies.drop()
다중 데이터 생성
db.movies.insertMany([{"title" : "Ghostbuster"}, {"title" : "E.T."}, {"title" : "Blade Runner"}]);
조회 결과
- 여러 도큐먼트를 단일 컬렉션에 삽입하는데 매우 유용
- 얼마까지 데이터를 입력할 수 있는가? - 책 필자는 48MB 라고 언급
- 하지만 현재 실습환경 MongoDB 6.X 버전은 아래와 같음
MongoDB 6.X 버전의 임계 값
현재는 해당링크 에 100,000개의 임계값을 가진다고 나와있고,
해당 숫자는 한번에 넣을 수 있는 _id의 개수이다.
다만, 용량에 대한 언급은 별도로 존재하지 않았다.
20만 개 인 경우, mongoDB에서 자체적으로 대기열을 생성하여 데이터를 삽입한다.
하지만 단일 용량을 여러번 호출 하는 것이 대기열을 이용하는 것 보다 빠르다고 한다.
insert() 명령 미지원
3.0 이전 버전에서는 주로 insert로 사용했는데,
CRUD 작업을 명확하고 일관된다는 MongoDB의 미션에 따라
해당 insert() 대신 insertOne(), insertMany()를 사용한다.
단일 삭제
db.movies.deleteOne({"_id" : 4})
MongoDB의 필터 특성상, 위와 같은 연산식을 주더라도 여러 값이 등장할 수 있고
deleteOne은 그 중에서 가장 먼저 일치하는 데이터를 삭제한다.
다중 삭제
db.movies.deleteMany({"year" : 1984})
위 명령을 통해 year가 1984인 모든 도큐먼트를 삭제할 수 있다.
다중 삭제 2
db.movies.deleteMany({})
movies 컬렉션안에 모든 데이터가 날라간다.
remove() 미지원
마찬가지로 deleteOne()과 deleteMany()를 쓴다.
도큐먼트 갱신
갱신은 Atomic한 특성을 갖고 있어, 하나의 도큐먼트에 대해
update 요청이 2번 발생할 수 있다. 이 경우에는 맨 마지막 요청이 최후의 승리자가 된다.
데이터 치환
{
_id: ObjectId("643ee230f5de6c870d83313d"),
name: 'joe',
friends: 32,
enemies: 2
}
friends와 enemies 필드를 relationship 이라는 서브 도큐먼트로 옮길 것 이다.
var joe = db.user.findOne({"name" : "joe"});
joe.relationship = {"friends" : joe.friends, "enemies" : joe.enemies};
joe.username = joe.name;
delete joe.friends;
delete joe.enemies;
delete joe.name;
db.user.replaceOne({"name" : "joe"}, joe);
findOne()으로 확인해보면 아래와 같은 결과를 볼 수 있다.
{
_id: ObjectId("643ee230f5de6c870d83313d"),
relationship: { friends: 32, enemies: 2 },
username: 'joe'
}
치환은 스키마 마이그레이션을 진행할 때 유용히 사용된다.
데이터 갱신 - $inc
{
_id: ObjectId("643ee4d4f5de6c870d83313f"),
url: 'www.example.com',
pageview: 52
}
페이지를 조회할 때마다 pageView를 1씩 증가하도록 구성하자.
db.analytics.updateOne({"url" : "www.example.com"}, {"$inc" : {"pageview" : 1}})
데이터 갱신 - $set
{
_id: ObjectId("643ee677f5de6c870d833140"),
name: 'joe',
age: 30,
sex: 'male',
location: 'Wisconsin'
}
필드 값을 변경할 수 있는데, 해당 필드가 존재하지 않으면 생성하여 추가한다.
db.users.updateOne({"name":"joe"}, {"$set" : {"favorite book" : "War and Peace"}})
추가된 모습이다.
하지만 favorite book만 별도 문자열 처리가 된 것을 볼 수 있다.
해당 이유는 찾지 못하였다.
또한, 이를 찾고자 공식문서를 살피는 와중
$set 부분은 "" 더블 쿼테이션을 포함하지 않아도 된다는 것을 확인했다.
데이터 갱신 - $unset
db.users.updateOne({"name" : "joe"},
... {$unset : {"favorite book" : 1}})
(... 은 쉘 개행시 자동으로 생긴다.)
{
_id: ObjectId("643ee677f5de6c870d833140"),
name: 'joe',
age: 30,
sex: 'male',
location: 'Wisconsin'
}
favorite book이 없어진 것을 볼 수 있다.
내장 데이터 갱신
db.blog.posts.updateOne({"author.name" : "joe"}, {$set : {"author.name" : "joe schmoe"}})
서브 도큐먼트로 author를 갖고
author는 name이라는 필드가 있는데
해당 name 필드를 "joe"에서 "joe schmoe"로 바꾼 것
제한자는 왜쓰는 것?
db.blog.posts.updateOne({"author.name" : "joe"}, {"author.name" : "joe schmoe"})
제한자 없이 명령을 치면 다큐먼트를 통으로 바꿔버린다고 한다.
하지만 현재는 제한자라는 개념을 통해 이를 보완했다고 한다.
배열 연산자 - $push
db.blog.posts.insertOne({"title" : "A blog post", "content" : "..."});
db.blog.posts.updateOne({"title" : "A blog post"}, {$push : {"comment" : {"name" : "joe", "email" : "joe@example.com", "content" : "nice post."}}})
코멘트가 배열형태로 추가된 것을 볼 수 있다.
{
_id: ObjectId("643eeba9f5de6c870d833141"),
title: 'A blog post',
content: '...',
comment: [ { name: 'joe', email: 'joe@example.com', content: 'nice post.' } ]
}
이외에도
- $push - 한개의 값을 배열로 넣을 때 (
- $each - 여러개의 배열에 값을 넣을 때
- $slice - 배열의 개수 제한
- $sort - 정렬할 수 있는 옵션
- $addToSet - 중복을 피하며 저장되는 $push (있으면 저장안됨)
- $ne - not 연산자처럼 동작 (예시 첨부
을 복합적으로 사용한다.
$ne
{
_id: ObjectId("61ba667dfe687fce2f042420"),
item: 'nuts',
quantity: 30,
carrier: { name: 'Shipit', fee: 3 }
},
{
_id: ObjectId("61ba667dfe687fce2f042421"),
item: 'bolts',
quantity: 50,
carrier: { name: 'Shipit', fee: 4 }
},
{
_id: ObjectId("61ba667dfe687fce2f042422"),
item: 'washers',
quantity: 10,
carrier: { name: 'Shipit', fee: 1 }
}
위 일때 아래와 같은 명령을 실행하면
db.inventory.updateMany( { "carrier.fee": { $ne: 1 } }, { $set: { "price": 9.99 } } )
{
_id: ObjectId("61ba66e2fe687fce2f042423"),
item: 'nuts',
quantity: 30,
carrier: { name: 'Shipit', fee: 3 },
price: 9.99
},
{
_id: ObjectId("61ba66e2fe687fce2f042424"),
item: 'bolts',
quantity: 50,
carrier: { name: 'Shipit', fee: 4 },
price: 9.99
},
{
_id: ObjectId("61ba66e2fe687fce2f042425"),
item: 'washers',
quantity: 10,
carrier: { name: 'Shipit', fee: 1 }
}
fee가 1인 도큐먼트에는 price 라는 필드가 추가되지 않은 것을 확인할 수 있다.
배열의 삭제 - $pop
db.students.insertOne( { _id: 1, scores: [ 8, 9, 10 ] } )
db.students.updateOne( { _id: 1 }, { $pop: { scores: -1 } } )
9와 10 값이 남는 것을 확인할 수 있고, STACK, QUEUE 처럼 사용할 수 있는 것이다.
-1은 배열의 처음부터 요소를 제거
1은 배열의 마지막부터 요소를 제거한다.
db.lists.updateOne({}, {$pull : {"todo" : "laundry"}})
위 명령은 pull 제한자를 사용하고, 조건과 일치하는 요소를 제거한다.
[1, 1, 2, 1] 에서 1을 pull 한다면 2만 남는다.
배열의 인덱스
"cart" : [
{
_id: ObjectId("61ba66e2fe687fce2f042423"),
item: 'nuts',
quantity: 30,
carrier: { name: 'Shipit', fee: 3 },
price: 9.99
},
{
_id: ObjectId("61ba66e2fe687fce2f042424"),
item: 'bolts',
quantity: 50,
carrier: { name: 'Shipit', fee: 4 },
price: 9.99
},
{
_id: ObjectId("61ba66e2fe687fce2f042425"),
item: 'washers',
quantity: 10,
carrier: { name: 'Shipit', fee: 1 }
price: 9.99
}
]
cart 배열을 정의하고 bolts의 fee를 변경하면 아래와 같을 것
db.shop.updateOne({"cart" : cart_id},
... {$inc : {"cart.1.fee" : 10}})
위 그대로 명령을 치면 좋지만 여기서 cart_id를 모르기 때문에 다른 방법으로 데이터를 찾아와야한다.
db.shop.updateOne({"cart.item" : "bolts"},
... {$inc : {"cart.$.fee" : 10}})
여기서 bolts가 2개 이상이라면 처음 bolts만 변경된다.
배열 필터를 이용한 갱신
db.blog.updateOne(
{"post" : post_id},
{$set :
{ "comments.$[elem].hidden" : true } },
{
arrayFilters: [ { "elem.votes" : { $lte: -5} } ]
}
)
위 명령은 arrayFilters를 도입하여, 반대표가 5표 이상인 댓글을 숨길 수 있다.
comments 배열에 각 요소에 대해 elem을 정의하고, elem의 votes가 -5 이하면 hidden 필드를 추가하여 true로 설정한다.
갱신입력 - (update + insert) updateOne(), updateMany()의 3번째 parameter
ad.analytics.updateOne({"url : "/blog"}, {"$inc" : {"pagevies" : 1}}, {"upsert" : true})
없으면 만들고, 있으면 업데이트한다.
다중 도큐먼트 갱신
db.users.insertMany([{birthday: "10/13/1978"},{birthday: "10/13/1978"},{birthday: "10/13/1978"}])
db.users.updateMany({"birthday" : "10/13/1978"}, {$set : {"gift" : "Happy"}})
그렇다. 맞다. 컬렉션 자체를 변경하거나 특정 사용자에게 새로운 정보를 추가할 때 쓰기 좋다.
참 긴 글이다.
'Infra > MongoDB' 카테고리의 다른 글
MongoDB - (6) - 인덱싱2 (0) | 2023.04.22 |
---|---|
MongoDB - (5) - 인덱싱 (0) | 2023.04.21 |
MongoDB - (4) - 쿼리 (0) | 2023.04.20 |
MongoDB - (2) - CRUD와 데이터타입 (0) | 2023.04.18 |
MongoDB - (1) - MongoDB 소개 (0) | 2023.04.18 |
댓글