예전 MongoDB 자료에 나오는 group(), db.eval(), mapReduce 는 지금 버전에서 없어졌거나 쓰지 않는다. 지금 쓰는 방식 기준으로 정리했다.
1. 개수 세기
|
1 2 3 |
db.person.countDocuments({}) // 조건에 맞는 정확한 개수 db.person.countDocuments({ name: "neo" }) db.person.estimatedDocumentCount() // 메타데이터로 빠르게 전체 개수 |
예전의 db.collection.count() 와 cursor.count() 는 deprecated 다.
2. 중복 없는 값 (distinct)
|
1 2 |
db.person.distinct("age") db.phones.distinct("components.number", { "components.number": { $lt: 5550005 } }) |
3. 집계 파이프라인
문서가 단계(stage)를 차례로 통과하며 걸러지고 바뀌는 구조다. 유닉스 파이프와 같은 생각이다. 예전 group() 명령(4.2 에서 제거)은 $group 단계로 대신한다.
| 단계 | SQL 로 치면 | 하는 일 |
|---|---|---|
$match |
WHERE / HAVING | 조건에 맞는 문서만 남김 |
$project |
SELECT | 필드 선택, 계산 필드 추가 |
$group |
GROUP BY | 키로 묶고 $sum, $avg, $min, $max, $push, $addToSet 등으로 집계 |
$sort |
ORDER BY | 정렬 |
$limit / $skip |
LIMIT / OFFSET | 개수 제한, 건너뛰기 |
$unwind |
– | 배열 필드를 원소마다 한 문서로 펼침 |
$lookup |
JOIN | 다른 컬렉션과 조인 |
$out / $merge |
INSERT INTO … SELECT | 결과를 컬렉션에 저장 |
4. 예제: 기사를 가장 많이 쓴 기자 5명
|
1 2 3 4 5 |
db.articles.aggregate([ { $group: { _id: "$author", count: { $sum: 1 } } }, // 기자별로 묶어서 개수 { $sort: { count: -1 } }, // 많은 순 { $limit: 5 } ]) |
$match 는 되도록 앞에 둔다. 앞 단계에서 문서를 줄여야 인덱스도 타고 뒤 단계가 가볍다.
5. 알아 둘 제한
- 각 단계는 기본 100MB 메모리 제한이 있다. 큰 데이터는
{ allowDiskUse: true }옵션을 준다. 6.0 부터는 필요하면 자동으로 디스크를 쓴다. - 결과는 커서로 받기 때문에 전체 크기 제한은 없다. 다만 결과 문서 하나는 16MB 를 넘을 수 없다.
mapReduce는 5.0 부터 deprecated 다. 같은 일은 집계 파이프라인($group,$accumulator)으로 한다.- 서버에서 자바스크립트를 실행하던
db.eval()은 4.2 에서 제거되었다. 업데이트도updateMany에 집계 파이프라인을 넘겨 서버에서 바로 처리할 수 있다.

Leave a Reply