<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://kimjaehyun.co.kr/feed.xml" rel="self" type="application/atom+xml" /><link href="https://kimjaehyun.co.kr/" rel="alternate" type="text/html" /><updated>2026-05-05T15:08:12+00:00</updated><id>https://kimjaehyun.co.kr/feed.xml</id><title type="html">꿰보노트</title><subtitle>프로그래밍과 소프트웨어 정보 및 클라우드 개발에 대한 정보를 공유하는 블로그 입니다. 꿰보노트 / 꿰보Note / 꿰어야 보배</subtitle><author><name>devjaedol</name></author><entry><title type="html">[InfluxDB] 01. InfluxDB 소개 및 설치</title><link href="https://kimjaehyun.co.kr/influxdb/influxdb-01-intro/" rel="alternate" type="text/html" title="[InfluxDB] 01. InfluxDB 소개 및 설치" /><published>2026-05-05T00:00:00+00:00</published><updated>2026-05-05T00:00:00+00:00</updated><id>https://kimjaehyun.co.kr/influxdb/influxdb-01-intro</id><content type="html" xml:base="https://kimjaehyun.co.kr/influxdb/influxdb-01-intro/"><![CDATA[<p>InfluxDB의 기본 개념, 장단점, 적합한 사용 사례, 설치 방법을 알아봅니다.</p>

<h1 id="influxdb란">InfluxDB란?</h1>

<p>InfluxDB는 시계열(Time Series) 데이터에 특화된 오픈소스 데이터베이스입니다.  <br />
시간 순서로 기록되는 대량의 데이터를 빠르게 쓰고, 시간 범위 기반으로 효율적으로 조회할 수 있도록 설계되었습니다.</p>

<h2 id="시계열-데이터란">시계열 데이터란?</h2>

<p>시계열 데이터는 시간에 따라 연속적으로 기록되는 데이터입니다.</p>

<table>
  <thead>
    <tr>
      <th>예시</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>서버 모니터링</td>
      <td>CPU 사용률, 메모리, 디스크 I/O (매초)</td>
    </tr>
    <tr>
      <td>IoT 센서</td>
      <td>온도, 습도, 압력 (매초~매분)</td>
    </tr>
    <tr>
      <td>금융 데이터</td>
      <td>주가, 환율, 거래량 (매초)</td>
    </tr>
    <tr>
      <td>애플리케이션 메트릭</td>
      <td>응답 시간, 에러율, 요청 수</td>
    </tr>
    <tr>
      <td>네트워크 트래픽</td>
      <td>대역폭, 패킷 수, 지연 시간</td>
    </tr>
    <tr>
      <td>스마트 팩토리</td>
      <td>설비 가동률, 생산량, 불량률</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="왜-influxdb를-사용하는가">왜 InfluxDB를 사용하는가?</h2>

<h3 id="rdbms로-시계열-데이터를-처리할-때의-문제">RDBMS로 시계열 데이터를 처리할 때의 문제</h3>

<table>
  <thead>
    <tr>
      <th>문제</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>쓰기 성능</td>
      <td>초당 수만~수십만 건 삽입 시 RDBMS는 한계</td>
    </tr>
    <tr>
      <td>저장 효율</td>
      <td>시계열 데이터는 압축 가능하지만 RDBMS는 범용 저장</td>
    </tr>
    <tr>
      <td>조회 패턴</td>
      <td>시간 범위 + 집계 쿼리에 RDBMS 인덱스 비효율</td>
    </tr>
    <tr>
      <td>데이터 보존</td>
      <td>오래된 데이터 자동 삭제/다운샘플링 어려움</td>
    </tr>
    <tr>
      <td>테이블 크기</td>
      <td>수억~수십억 행이 빠르게 쌓여 관리 어려움</td>
    </tr>
  </tbody>
</table>

<h3 id="influxdb가-해결하는-것">InfluxDB가 해결하는 것</h3>

<table>
  <thead>
    <tr>
      <th>기능</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>고속 쓰기</td>
      <td>초당 수십만 포인트 삽입 가능</td>
    </tr>
    <tr>
      <td>시간 기반 압축</td>
      <td>TSM(Time-Structured Merge Tree) 엔진</td>
    </tr>
    <tr>
      <td>자동 다운샘플링</td>
      <td>오래된 데이터를 요약본으로 변환</td>
    </tr>
    <tr>
      <td>보존 정책</td>
      <td>일정 기간 후 자동 삭제 (Retention Policy)</td>
    </tr>
    <tr>
      <td>시간 범위 쿼리 최적화</td>
      <td>시간 인덱스 기본 내장</td>
    </tr>
    <tr>
      <td>연속 쿼리</td>
      <td>실시간 집계 자동 실행</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="influxdb-장단점">InfluxDB 장단점</h2>

<h3 id="장점">장점</h3>

<table>
  <thead>
    <tr>
      <th>장점</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>시계열 최적화</td>
      <td>시간 기반 쓰기/읽기에 최적화된 스토리지 엔진</td>
    </tr>
    <tr>
      <td>고속 삽입</td>
      <td>초당 수십만 포인트 쓰기 가능</td>
    </tr>
    <tr>
      <td>자동 데이터 관리</td>
      <td>Retention Policy로 오래된 데이터 자동 삭제</td>
    </tr>
    <tr>
      <td>내장 함수 풍부</td>
      <td>이동 평균, 미분, 적분, 예측 등 시계열 전용 함수</td>
    </tr>
    <tr>
      <td>스키마리스</td>
      <td>태그/필드를 자유롭게 추가 가능</td>
    </tr>
    <tr>
      <td>에코시스템</td>
      <td>Telegraf(수집), Chronograf(시각화), Kapacitor(알림)</td>
    </tr>
    <tr>
      <td>Grafana 연동</td>
      <td>대시보드 시각화 도구와 완벽 호환</td>
    </tr>
    <tr>
      <td>압축 효율</td>
      <td>시계열 데이터 특성을 활용한 높은 압축률</td>
    </tr>
  </tbody>
</table>

<h3 id="단점">단점</h3>

<table>
  <thead>
    <tr>
      <th>단점</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>범용 DB 아님</td>
      <td>JOIN, 트랜잭션, 복잡한 관계 표현 불가</td>
    </tr>
    <tr>
      <td>업데이트 비효율</td>
      <td>기존 데이터 수정에 적합하지 않음 (Append-only 설계)</td>
    </tr>
    <tr>
      <td>삭제 비용</td>
      <td>개별 포인트 삭제가 비효율적</td>
    </tr>
    <tr>
      <td>높은 카디널리티 주의</td>
      <td>태그 값 종류가 너무 많으면 성능 저하</td>
    </tr>
    <tr>
      <td>클러스터링 제한</td>
      <td>OSS 버전은 단일 노드 (Enterprise만 클러스터)</td>
    </tr>
    <tr>
      <td>학습 곡선</td>
      <td>Flux 언어 (InfluxDB 2.x)가 독특함</td>
    </tr>
    <tr>
      <td>메모리 사용</td>
      <td>인덱스를 메모리에 유지하므로 RAM 필요</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="언제-influxdb를-사용해야-하는가">언제 InfluxDB를 사용해야 하는가?</h2>

<h3 id="적합한-경우-">적합한 경우 ✅</h3>

<table>
  <thead>
    <tr>
      <th>사용 사례</th>
      <th>이유</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>서버/인프라 모니터링</td>
      <td>대량 메트릭, 시간 범위 조회, 대시보드</td>
    </tr>
    <tr>
      <td>IoT 센서 데이터</td>
      <td>초당 수만 건 삽입, 자동 보존 정책</td>
    </tr>
    <tr>
      <td>애플리케이션 성능 모니터링 (APM)</td>
      <td>응답 시간, 에러율 추적</td>
    </tr>
    <tr>
      <td>실시간 분석 대시보드</td>
      <td>Grafana 연동, 실시간 집계</td>
    </tr>
    <tr>
      <td>네트워크 모니터링</td>
      <td>트래픽, 대역폭, 패킷 분석</td>
    </tr>
    <tr>
      <td>DevOps 메트릭</td>
      <td>CI/CD 파이프라인, 배포 추적</td>
    </tr>
    <tr>
      <td>금융 시계열</td>
      <td>주가, 거래량 (단, 트랜잭션 불필요 시)</td>
    </tr>
    <tr>
      <td>스마트 팩토리</td>
      <td>설비 데이터, 생산 메트릭</td>
    </tr>
  </tbody>
</table>

<h3 id="부적합한-경우-">부적합한 경우 ❌</h3>

<table>
  <thead>
    <tr>
      <th>사용 사례</th>
      <th>이유</th>
      <th>대안</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>사용자 정보, 주문 관리</td>
      <td>관계형 데이터, 트랜잭션 필요</td>
      <td>PostgreSQL, MySQL</td>
    </tr>
    <tr>
      <td>문서 저장 (CMS)</td>
      <td>유연한 문서 구조 필요</td>
      <td>MongoDB</td>
    </tr>
    <tr>
      <td>캐시, 세션</td>
      <td>키-값 빠른 접근</td>
      <td>Redis</td>
    </tr>
    <tr>
      <td>전문 검색</td>
      <td>텍스트 검색</td>
      <td>Elasticsearch</td>
    </tr>
    <tr>
      <td>데이터 수정이 빈번한 경우</td>
      <td>Append-only 설계와 맞지 않음</td>
      <td>RDBMS</td>
    </tr>
    <tr>
      <td>복잡한 JOIN이 필요한 경우</td>
      <td>JOIN 미지원</td>
      <td>RDBMS</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="influxdb-버전-비교">InfluxDB 버전 비교</h2>

<table>
  <thead>
    <tr>
      <th>항목</th>
      <th>InfluxDB 1.x</th>
      <th>InfluxDB 2.x</th>
      <th>InfluxDB 3.x</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>쿼리 언어</td>
      <td>InfluxQL (SQL 유사)</td>
      <td>Flux (함수형)</td>
      <td>SQL + InfluxQL</td>
    </tr>
    <tr>
      <td>UI</td>
      <td>별도 (Chronograf)</td>
      <td>내장 웹 UI</td>
      <td>내장 웹 UI</td>
    </tr>
    <tr>
      <td>인증</td>
      <td>기본 인증</td>
      <td>토큰 기반</td>
      <td>토큰 기반</td>
    </tr>
    <tr>
      <td>조직/버킷</td>
      <td>Database/RP</td>
      <td>Organization/Bucket</td>
      <td>Database</td>
    </tr>
    <tr>
      <td>스토리지</td>
      <td>TSM</td>
      <td>TSM</td>
      <td>Apache Arrow + Parquet</td>
    </tr>
    <tr>
      <td>라이선스</td>
      <td>MIT</td>
      <td>MIT (OSS)</td>
      <td>Apache 2.0 (Core)</td>
    </tr>
  </tbody>
</table>

<blockquote>
  <p>이 강좌에서는 InfluxDB 2.x를 기준으로 설명합니다.</p>
</blockquote>

<hr />

<h2 id="설치">설치</h2>

<h3 id="docker-권장">Docker (권장)</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run <span class="nt">-d</span> <span class="se">\</span>
  <span class="nt">--name</span> influxdb <span class="se">\</span>
  <span class="nt">-p</span> 8086:8086 <span class="se">\</span>
  <span class="nt">-v</span> influxdb-data:/var/lib/influxdb2 <span class="se">\</span>
  <span class="nt">-e</span> <span class="nv">DOCKER_INFLUXDB_INIT_MODE</span><span class="o">=</span>setup <span class="se">\</span>
  <span class="nt">-e</span> <span class="nv">DOCKER_INFLUXDB_INIT_USERNAME</span><span class="o">=</span>admin <span class="se">\</span>
  <span class="nt">-e</span> <span class="nv">DOCKER_INFLUXDB_INIT_PASSWORD</span><span class="o">=</span>InfluxPass123! <span class="se">\</span>
  <span class="nt">-e</span> <span class="nv">DOCKER_INFLUXDB_INIT_ORG</span><span class="o">=</span>myorg <span class="se">\</span>
  <span class="nt">-e</span> <span class="nv">DOCKER_INFLUXDB_INIT_BUCKET</span><span class="o">=</span>mybucket <span class="se">\</span>
  <span class="nt">-e</span> <span class="nv">DOCKER_INFLUXDB_INIT_ADMIN_TOKEN</span><span class="o">=</span>my-super-secret-token <span class="se">\</span>
  influxdb:2

<span class="c"># 웹 UI 접속</span>
<span class="c"># http://localhost:8086</span>
</code></pre></div></div>

<h3 id="linux-ubuntu">Linux (Ubuntu)</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget https://dl.influxdata.com/influxdb/releases/influxdb2_2.7.x_amd64.deb
<span class="nb">sudo </span>dpkg <span class="nt">-i</span> influxdb2_2.7.x_amd64.deb
<span class="nb">sudo </span>systemctl start influxdb
<span class="nb">sudo </span>systemctl <span class="nb">enable </span>influxdb

<span class="c"># 초기 설정</span>
influx setup
</code></pre></div></div>

<h3 id="mac">Mac</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>brew <span class="nb">install </span>influxdb
brew services start influxdb

<span class="c"># 초기 설정</span>
influx setup
</code></pre></div></div>

<h3 id="windows">Windows</h3>
<ol>
  <li><a href="https://portal.influxdata.com/downloads/" target="_blank">InfluxDB 다운로드</a> 페이지에서 Windows 바이너리 다운로드</li>
  <li>압축 해제 후 <code class="language-plaintext highlighter-rouge">influxd.exe</code> 실행</li>
  <li>브라우저에서 <code class="language-plaintext highlighter-rouge">http://localhost:8086</code> 접속하여 초기 설정</li>
</ol>

<h3 id="설치-확인">설치 확인</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>influx version
influx ping
<span class="c"># 웹 UI: http://localhost:8086</span>
</code></pre></div></div>

<hr />

<h2 id="접속-방법">접속 방법</h2>

<h3 id="influx-cli">influx CLI</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 토큰 인증</span>
influx config create <span class="se">\</span>
  <span class="nt">--config-name</span> default <span class="se">\</span>
  <span class="nt">--host-url</span> http://localhost:8086 <span class="se">\</span>
  <span class="nt">--org</span> myorg <span class="se">\</span>
  <span class="nt">--token</span> my-super-secret-token <span class="se">\</span>
  <span class="nt">--active</span>

<span class="c"># 버킷 목록</span>
influx bucket list

<span class="c"># 쿼리 실행</span>
influx query <span class="s1">'from(bucket:"mybucket") |&gt; range(start: -1h)'</span>
</code></pre></div></div>

<h3 id="http-api">HTTP API</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 데이터 쓰기</span>
curl <span class="nt">-X</span> POST <span class="s2">"http://localhost:8086/api/v2/write?org=myorg&amp;bucket=mybucket"</span> <span class="se">\</span>
  <span class="nt">-H</span> <span class="s2">"Authorization: Token my-super-secret-token"</span> <span class="se">\</span>
  <span class="nt">-H</span> <span class="s2">"Content-Type: text/plain"</span> <span class="se">\</span>
  <span class="nt">--data-raw</span> <span class="s2">"cpu,host=server01 usage=45.2 1714900000000000000"</span>

<span class="c"># 데이터 조회</span>
curl <span class="nt">-X</span> POST <span class="s2">"http://localhost:8086/api/v2/query?org=myorg"</span> <span class="se">\</span>
  <span class="nt">-H</span> <span class="s2">"Authorization: Token my-super-secret-token"</span> <span class="se">\</span>
  <span class="nt">-H</span> <span class="s2">"Content-Type: application/vnd.flux"</span> <span class="se">\</span>
  <span class="nt">--data</span> <span class="s1">'from(bucket:"mybucket") |&gt; range(start: -1h)'</span>
</code></pre></div></div>

<hr />

<h2 id="tick-스택-influxdb-에코시스템">TICK 스택 (InfluxDB 에코시스템)</h2>

<table>
  <thead>
    <tr>
      <th>구성 요소</th>
      <th>역할</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Telegraf</td>
      <td>수집 (Collector)</td>
      <td>200+ 플러그인으로 메트릭 수집</td>
    </tr>
    <tr>
      <td>InfluxDB</td>
      <td>저장 (Storage)</td>
      <td>시계열 데이터 저장/조회</td>
    </tr>
    <tr>
      <td>Chronograf</td>
      <td>시각화 (Visualization)</td>
      <td>대시보드, 관리 UI (2.x는 내장)</td>
    </tr>
    <tr>
      <td>Kapacitor</td>
      <td>알림 (Alerting)</td>
      <td>실시간 스트림 처리, 알림 (2.x는 내장)</td>
    </tr>
  </tbody>
</table>

<blockquote>
  <p>InfluxDB 2.x에서는 Chronograf와 Kapacitor 기능이 내장되어 별도 설치가 불필요합니다.  <br />
시각화는 Grafana와 연동하는 것이 더 일반적입니다.</p>
</blockquote>

<p><span class="nav__sub-title">관련된 글 (influxdb &gt; lecture-influxdb)</span></p>
<ul>

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-06-admin-troubleshooting/">[InfluxDB] 06. 운영 관리와 Troubleshooting</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-05-task-alert/">[InfluxDB] 05. Task, 다운샘플링, 알림</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-04-telegraf/">[InfluxDB] 04. Telegraf (데이터 수집 에이전트)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-03-flux-query/">[InfluxDB] 03. Flux 쿼리 언어</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-02-data-model/">[InfluxDB] 02. 데이터 모델 (Measurement, Tag, Field)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-01-intro/">[InfluxDB] 01. InfluxDB 소개 및 설치</a></li>
             
        
      

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

</ul>]]></content><author><name>devjaedol</name></author><category term="influxdb" /><category term="influxdb" /><category term="timeseries" /><category term="influxdb강좌" /><category term="초급" /><category term="lecture-influxdb" /><summary type="html"><![CDATA[InfluxDB의 기본 개념, 장단점, 적합한 사용 사례, 설치 방법을 알아봅니다.]]></summary></entry><entry><title type="html">[InfluxDB] 02. 데이터 모델 (Measurement, Tag, Field)</title><link href="https://kimjaehyun.co.kr/influxdb/influxdb-02-data-model/" rel="alternate" type="text/html" title="[InfluxDB] 02. 데이터 모델 (Measurement, Tag, Field)" /><published>2026-05-05T00:00:00+00:00</published><updated>2026-05-05T00:00:00+00:00</updated><id>https://kimjaehyun.co.kr/influxdb/influxdb-02-data-model</id><content type="html" xml:base="https://kimjaehyun.co.kr/influxdb/influxdb-02-data-model/"><![CDATA[<p>InfluxDB의 핵심 데이터 모델인 Measurement, Tag, Field, Timestamp를 정리합니다.</p>

<h1 id="데이터-모델-개요">데이터 모델 개요</h1>

<p>InfluxDB의 데이터 모델은 RDBMS와 완전히 다릅니다.  <br />
시계열 데이터에 최적화된 구조로, 모든 데이터 포인트는 반드시 타임스탬프를 가집니다.</p>

<h2 id="rdbms--influxdb-용어-매핑">RDBMS ↔ InfluxDB 용어 매핑</h2>

<table>
  <thead>
    <tr>
      <th>RDBMS</th>
      <th>InfluxDB</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Database</td>
      <td>Bucket</td>
      <td>데이터 저장 공간 (보존 정책 포함)</td>
    </tr>
    <tr>
      <td>Table</td>
      <td>Measurement</td>
      <td>데이터 그룹 (테이블과 유사)</td>
    </tr>
    <tr>
      <td>인덱스 컬럼</td>
      <td>Tag</td>
      <td>메타데이터 (자동 인덱싱)</td>
    </tr>
    <tr>
      <td>일반 컬럼</td>
      <td>Field</td>
      <td>실제 측정값 (인덱싱 안됨)</td>
    </tr>
    <tr>
      <td>Primary Key</td>
      <td>Timestamp</td>
      <td>시간 (자동, 필수)</td>
    </tr>
    <tr>
      <td>Row</td>
      <td>Point</td>
      <td>하나의 데이터 포인트</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="line-protocol-데이터-쓰기-형식">Line Protocol (데이터 쓰기 형식)</h2>

<p>InfluxDB에 데이터를 쓸 때 사용하는 텍스트 형식입니다.</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;measurement&gt;,&lt;tag_key&gt;=&lt;tag_value&gt;,... &lt;field_key&gt;=&lt;field_value&gt;,... &lt;timestamp&gt;
</code></pre></div></div>

<h3 id="예시">예시</h3>
<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cpu,host=server01,region=kr-central usage_user=45.2,usage_system=12.1 1714900000000000000
cpu,host=server02,region=kr-central usage_user=32.8,usage_system=8.5 1714900000000000000
temperature,sensor=s1,location=factory1 value=23.5 1714900000000000000
</code></pre></div></div>

<h3 id="구성-요소-상세">구성 요소 상세</h3>

<table>
  <thead>
    <tr>
      <th>구성 요소</th>
      <th style="text-align: center">필수</th>
      <th>설명</th>
      <th>예시</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Measurement</td>
      <td style="text-align: center">✅</td>
      <td>데이터 그룹명</td>
      <td><code class="language-plaintext highlighter-rouge">cpu</code>, <code class="language-plaintext highlighter-rouge">temperature</code>, <code class="language-plaintext highlighter-rouge">http_requests</code></td>
    </tr>
    <tr>
      <td>Tag (key=value)</td>
      <td style="text-align: center">❌</td>
      <td>메타데이터, 자동 인덱싱</td>
      <td><code class="language-plaintext highlighter-rouge">host=server01</code>, <code class="language-plaintext highlighter-rouge">region=kr</code></td>
    </tr>
    <tr>
      <td>Field (key=value)</td>
      <td style="text-align: center">✅</td>
      <td>실제 측정값, 인덱싱 안됨</td>
      <td><code class="language-plaintext highlighter-rouge">usage=45.2</code>, <code class="language-plaintext highlighter-rouge">count=100</code></td>
    </tr>
    <tr>
      <td>Timestamp</td>
      <td style="text-align: center">❌</td>
      <td>나노초 Unix 타임스탬프 (생략 시 현재 시간)</td>
      <td><code class="language-plaintext highlighter-rouge">1714900000000000000</code></td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="tag-vs-field-핵심-구분">Tag vs Field (핵심 구분)</h2>

<p>이 구분을 잘못하면 성능에 큰 영향을 미칩니다.</p>

<table>
  <thead>
    <tr>
      <th>항목</th>
      <th>Tag</th>
      <th>Field</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>인덱싱</td>
      <td>✅ 자동 인덱싱</td>
      <td>❌ 인덱싱 안됨</td>
    </tr>
    <tr>
      <td>데이터 타입</td>
      <td>문자열만</td>
      <td>정수, 실수, 문자열, 불리언</td>
    </tr>
    <tr>
      <td>WHERE 조건</td>
      <td>빠름 (인덱스 사용)</td>
      <td>느림 (전체 스캔)</td>
    </tr>
    <tr>
      <td>GROUP BY</td>
      <td>가능</td>
      <td>불가</td>
    </tr>
    <tr>
      <td>카디널리티</td>
      <td>낮아야 좋음</td>
      <td>제한 없음</td>
    </tr>
    <tr>
      <td>용도</td>
      <td>분류, 필터링 기준</td>
      <td>실제 측정값</td>
    </tr>
  </tbody>
</table>

<h3 id="tag로-적합한-것-">Tag로 적합한 것 ✅</h3>
<ul>
  <li>호스트명 (<code class="language-plaintext highlighter-rouge">host=server01</code>)</li>
  <li>리전 (<code class="language-plaintext highlighter-rouge">region=kr-central</code>)</li>
  <li>센서 ID (<code class="language-plaintext highlighter-rouge">sensor=s1</code>)</li>
  <li>환경 (<code class="language-plaintext highlighter-rouge">env=production</code>)</li>
  <li>서비스명 (<code class="language-plaintext highlighter-rouge">service=api-gateway</code>)</li>
</ul>

<h3 id="field로-적합한-것-">Field로 적합한 것 ✅</h3>
<ul>
  <li>CPU 사용률 (<code class="language-plaintext highlighter-rouge">usage=45.2</code>)</li>
  <li>온도 (<code class="language-plaintext highlighter-rouge">temperature=23.5</code>)</li>
  <li>응답 시간 (<code class="language-plaintext highlighter-rouge">response_time=120</code>)</li>
  <li>요청 수 (<code class="language-plaintext highlighter-rouge">count=1500</code>)</li>
  <li>에러 수 (<code class="language-plaintext highlighter-rouge">errors=3</code>)</li>
</ul>

<h3 id="tag로-부적합한-것--높은-카디널리티">Tag로 부적합한 것 ❌ (높은 카디널리티)</h3>
<ul>
  <li>사용자 ID (수백만 종류)</li>
  <li>요청 URL (무한 종류)</li>
  <li>타임스탬프 문자열</li>
  <li>UUID</li>
</ul>

<blockquote>
  <p>카디널리티(고유 값 수)가 높은 데이터를 Tag로 설정하면 인덱스가 비대해져 메모리 부족과 성능 저하가 발생합니다.</p>
</blockquote>

<hr />

<h2 id="series-시리즈">Series (시리즈)</h2>

<p>Series는 동일한 Measurement + Tag 조합을 가진 데이터 포인트의 집합입니다.  <br />
InfluxDB 성능의 핵심 지표는 <strong>시리즈 카디널리티</strong>(총 시리즈 수)입니다.</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code># 아래는 3개의 서로 다른 시리즈
cpu,host=server01,region=kr    → Series 1
cpu,host=server02,region=kr    → Series 2
cpu,host=server01,region=us    → Series 3
</code></pre></div></div>

<h3 id="시리즈-카디널리티-계산">시리즈 카디널리티 계산</h3>
<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>시리즈 수 = Measurement 수 × Tag 조합 수

예: cpu measurement, host 100대, region 3개
시리즈 수 = 1 × 100 × 3 = 300 시리즈 (양호)

예: http_requests, user_id 100만명, endpoint 50개
시리즈 수 = 1 × 1,000,000 × 50 = 5천만 시리즈 (위험!)
</code></pre></div></div>

<hr />

<h2 id="bucket-버킷">Bucket (버킷)</h2>

<p>InfluxDB 2.x에서 Bucket은 데이터 저장 공간 + 보존 정책을 합친 개념입니다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 버킷 생성 (30일 보존)</span>
influx bucket create <span class="se">\</span>
  <span class="nt">--name</span> monitoring <span class="se">\</span>
  <span class="nt">--org</span> myorg <span class="se">\</span>
  <span class="nt">--retention</span> 30d

<span class="c"># 버킷 목록</span>
influx bucket list

<span class="c"># 버킷 삭제</span>
influx bucket delete <span class="nt">--name</span> monitoring
</code></pre></div></div>

<h3 id="보존-기간-retention">보존 기간 (Retention)</h3>

<table>
  <thead>
    <tr>
      <th>설정</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">0</code></td>
      <td>무기한 보존</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">24h</code></td>
      <td>24시간</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">7d</code></td>
      <td>7일</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">30d</code></td>
      <td>30일</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">365d</code></td>
      <td>1년</td>
    </tr>
  </tbody>
</table>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 보존 기간 변경</span>
influx bucket update <span class="nt">--name</span> monitoring <span class="nt">--retention</span> 90d
</code></pre></div></div>

<hr />

<h2 id="데이터-쓰기">데이터 쓰기</h2>

<h3 id="influx-cli">influx CLI</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>influx write <span class="se">\</span>
  <span class="nt">--bucket</span> mybucket <span class="se">\</span>
  <span class="nt">--org</span> myorg <span class="se">\</span>
  <span class="nt">--precision</span> s <span class="se">\</span>
  <span class="s2">"cpu,host=server01 usage_user=45.2,usage_system=12.1 1714900000"</span>
</code></pre></div></div>

<h3 id="여러-포인트-한번에-쓰기">여러 포인트 한번에 쓰기</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>influx write <span class="nt">--bucket</span> mybucket <span class="nt">--org</span> myorg <span class="nt">--precision</span> ns <span class="o">&lt;&lt;</span> <span class="no">EOF</span><span class="sh">
cpu,host=server01 usage_user=45.2,usage_system=12.1 1714900000000000000
cpu,host=server02 usage_user=32.8,usage_system=8.5 1714900000000000000
memory,host=server01 used_percent=72.5,available=8589934592 1714900000000000000
</span><span class="no">EOF
</span></code></pre></div></div>

<h3 id="파일에서-쓰기">파일에서 쓰기</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># data.lp (Line Protocol 파일)</span>
influx write <span class="nt">--bucket</span> mybucket <span class="nt">--org</span> myorg <span class="nt">--file</span> data.lp

<span class="c"># CSV 파일</span>
influx write <span class="nt">--bucket</span> mybucket <span class="nt">--org</span> myorg <span class="se">\</span>
  <span class="nt">--file</span> data.csv <span class="se">\</span>
  <span class="nt">--header</span> <span class="s2">"#constant measurement,cpu"</span> <span class="se">\</span>
  <span class="nt">--header</span> <span class="s2">"#datatype tag,double,double,dateTime:RFC3339"</span>
</code></pre></div></div>

<hr />

<h2 id="데이터-모델-설계-예시">데이터 모델 설계 예시</h2>

<h3 id="서버-모니터링">서버 모니터링</h3>
<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Measurement: cpu
cpu,host=web01,region=kr,env=prod usage_user=45.2,usage_system=12.1,usage_idle=42.7

# Measurement: memory
memory,host=web01,region=kr,env=prod used_percent=72.5,available=8589934592

# Measurement: disk
disk,host=web01,path=/,device=sda1 used_percent=65.3,free=107374182400
</code></pre></div></div>

<h3 id="iot-센서">IoT 센서</h3>
<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Measurement: temperature
temperature,sensor_id=s001,location=factory1,floor=1F value=23.5,humidity=45.2

# Measurement: vibration
vibration,machine_id=m001,line=A frequency=120.5,amplitude=0.03
</code></pre></div></div>

<h3 id="웹-애플리케이션-메트릭">웹 애플리케이션 메트릭</h3>
<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Measurement: http_requests
http_requests,method=GET,endpoint=/api/users,status=200 count=1,response_time=45

# Measurement: errors
errors,service=api,level=error count=1,message="timeout"
</code></pre></div></div>

<p><span class="nav__sub-title">관련된 글 (influxdb &gt; lecture-influxdb)</span></p>
<ul>

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-06-admin-troubleshooting/">[InfluxDB] 06. 운영 관리와 Troubleshooting</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-05-task-alert/">[InfluxDB] 05. Task, 다운샘플링, 알림</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-04-telegraf/">[InfluxDB] 04. Telegraf (데이터 수집 에이전트)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-03-flux-query/">[InfluxDB] 03. Flux 쿼리 언어</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-02-data-model/">[InfluxDB] 02. 데이터 모델 (Measurement, Tag, Field)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-01-intro/">[InfluxDB] 01. InfluxDB 소개 및 설치</a></li>
             
        
      

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

</ul>]]></content><author><name>devjaedol</name></author><category term="influxdb" /><category term="influxdb" /><category term="timeseries" /><category term="influxdb강좌" /><category term="초급" /><category term="lecture-influxdb" /><summary type="html"><![CDATA[InfluxDB의 핵심 데이터 모델인 Measurement, Tag, Field, Timestamp를 정리합니다.]]></summary></entry><entry><title type="html">[InfluxDB] 03. Flux 쿼리 언어</title><link href="https://kimjaehyun.co.kr/influxdb/influxdb-03-flux-query/" rel="alternate" type="text/html" title="[InfluxDB] 03. Flux 쿼리 언어" /><published>2026-05-05T00:00:00+00:00</published><updated>2026-05-05T00:00:00+00:00</updated><id>https://kimjaehyun.co.kr/influxdb/influxdb-03-flux-query</id><content type="html" xml:base="https://kimjaehyun.co.kr/influxdb/influxdb-03-flux-query/"><![CDATA[<p>InfluxDB 2.x의 쿼리 언어인 Flux의 기본 문법과 주요 함수를 정리합니다.</p>

<h1 id="flux란">Flux란?</h1>

<p>Flux는 InfluxDB 2.x에서 사용하는 함수형 데이터 스크립팅 언어입니다.  <br />
파이프(<code class="language-plaintext highlighter-rouge">|&gt;</code>) 연산자로 데이터를 단계별로 변환하는 파이프라인 방식입니다.</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>데이터 소스 |&gt; 필터 |&gt; 변환 |&gt; 집계 |&gt; 출력
</code></pre></div></div>

<hr />

<h2 id="기본-쿼리-구조">기본 쿼리 구조</h2>

<h3 id="필수-3요소">필수 3요소</h3>
<pre><code class="language-flux">from(bucket: "mybucket")        // 1. 데이터 소스
  |&gt; range(start: -1h)          // 2. 시간 범위 (필수)
  |&gt; filter(fn: (r) =&gt; r._measurement == "cpu")  // 3. 필터
</code></pre>

<h3 id="시간-범위-range">시간 범위 (range)</h3>
<pre><code class="language-flux">// 상대 시간
|&gt; range(start: -1h)              // 최근 1시간
|&gt; range(start: -7d)              // 최근 7일
|&gt; range(start: -30m, stop: -5m)  // 30분 전 ~ 5분 전

// 절대 시간
|&gt; range(start: 2026-05-01T00:00:00Z, stop: 2026-05-05T23:59:59Z)
</code></pre>

<h3 id="필터-filter">필터 (filter)</h3>
<pre><code class="language-flux">// 단일 조건
|&gt; filter(fn: (r) =&gt; r._measurement == "cpu")

// 다중 조건 (AND)
|&gt; filter(fn: (r) =&gt; r._measurement == "cpu" and r.host == "server01")

// OR 조건
|&gt; filter(fn: (r) =&gt; r.host == "server01" or r.host == "server02")

// 필드 필터
|&gt; filter(fn: (r) =&gt; r._field == "usage_user")

// 값 필터
|&gt; filter(fn: (r) =&gt; r._value &gt; 80.0)

// 정규식
|&gt; filter(fn: (r) =&gt; r.host =~ /server0[1-3]/)
</code></pre>

<hr />

<h2 id="집계-함수">집계 함수</h2>

<h3 id="기본-집계">기본 집계</h3>
<pre><code class="language-flux">// 평균
from(bucket: "mybucket")
  |&gt; range(start: -1h)
  |&gt; filter(fn: (r) =&gt; r._measurement == "cpu" and r._field == "usage_user")
  |&gt; mean()

// 최대/최소
|&gt; max()
|&gt; min()

// 합계/개수
|&gt; sum()
|&gt; count()

// 마지막/첫 번째 값
|&gt; last()
|&gt; first()

// 중앙값/백분위
|&gt; median()
|&gt; quantile(q: 0.95)    // 95 퍼센타일
</code></pre>

<h3 id="시간-윈도우-집계-aggregatewindow">시간 윈도우 집계 (aggregateWindow)</h3>
<pre><code class="language-flux">// 5분 간격 평균
from(bucket: "mybucket")
  |&gt; range(start: -1h)
  |&gt; filter(fn: (r) =&gt; r._measurement == "cpu" and r._field == "usage_user")
  |&gt; aggregateWindow(every: 5m, fn: mean, createEmpty: false)

// 1시간 간격 최대값
|&gt; aggregateWindow(every: 1h, fn: max)

// 1일 간격 합계
|&gt; aggregateWindow(every: 1d, fn: sum)
</code></pre>

<h3 id="그룹핑-group">그룹핑 (group)</h3>
<pre><code class="language-flux">// 호스트별 그룹핑 후 평균
from(bucket: "mybucket")
  |&gt; range(start: -1h)
  |&gt; filter(fn: (r) =&gt; r._measurement == "cpu")
  |&gt; group(columns: ["host"])
  |&gt; mean()

// 그룹 해제
|&gt; group()
</code></pre>

<hr />

<h2 id="변환-함수">변환 함수</h2>

<h3 id="정렬제한">정렬/제한</h3>
<pre><code class="language-flux">// 정렬
|&gt; sort(columns: ["_time"], desc: true)
|&gt; sort(columns: ["_value"], desc: true)

// 상위 N개
|&gt; top(n: 10, columns: ["_value"])
|&gt; bottom(n: 5, columns: ["_value"])

// 제한
|&gt; limit(n: 100)
|&gt; tail(n: 10)    // 마지막 10개
</code></pre>

<h3 id="수학-연산">수학 연산</h3>
<pre><code class="language-flux">// 값 변환
|&gt; map(fn: (r) =&gt; ({ r with _value: r._value * 100.0 }))

// 새 컬럼 추가
|&gt; map(fn: (r) =&gt; ({ r with celsius: (r._value - 32.0) * 5.0 / 9.0 }))

// 절대값, 반올림
|&gt; math.abs()
|&gt; math.round(precision: 2)
</code></pre>

<h3 id="시간-함수">시간 함수</h3>
<pre><code class="language-flux">// 시간 이동
|&gt; timeShift(duration: -1d)

// 시간 단위 추출
|&gt; map(fn: (r) =&gt; ({ r with hour: date.hour(t: r._time) }))
</code></pre>

<h3 id="피벗-pivot">피벗 (Pivot)</h3>
<pre><code class="language-flux">// 필드를 컬럼으로 변환
from(bucket: "mybucket")
  |&gt; range(start: -1h)
  |&gt; filter(fn: (r) =&gt; r._measurement == "cpu")
  |&gt; pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value")
// 결과: _time | usage_user | usage_system | usage_idle
</code></pre>

<hr />

<h2 id="고급-함수">고급 함수</h2>

<h3 id="이동-평균-moving-average">이동 평균 (Moving Average)</h3>
<pre><code class="language-flux">|&gt; movingAverage(n: 5)          // 단순 이동 평균 (5포인트)
|&gt; exponentialMovingAverage(n: 10)  // 지수 이동 평균
|&gt; timedMovingAverage(every: 5m, period: 15m)  // 시간 기반
</code></pre>

<h3 id="변화율-derivative">변화율 (Derivative)</h3>
<pre><code class="language-flux">// 초당 변화율
|&gt; derivative(unit: 1s, nonNegative: true)

// 차이 (현재 - 이전)
|&gt; difference(nonNegative: true)

// 증가분 (카운터용)
|&gt; increase()
</code></pre>

<h3 id="조건부-알림">조건부 알림</h3>
<pre><code class="language-flux">// 임계값 초과 필터
from(bucket: "mybucket")
  |&gt; range(start: -5m)
  |&gt; filter(fn: (r) =&gt; r._measurement == "cpu" and r._field == "usage_user")
  |&gt; filter(fn: (r) =&gt; r._value &gt; 90.0)
</code></pre>

<h3 id="다운샘플링-데이터-축소">다운샘플링 (데이터 축소)</h3>
<pre><code class="language-flux">// 원본 데이터를 1시간 평균으로 축소하여 다른 버킷에 저장
from(bucket: "raw_data")
  |&gt; range(start: -24h)
  |&gt; filter(fn: (r) =&gt; r._measurement == "cpu")
  |&gt; aggregateWindow(every: 1h, fn: mean)
  |&gt; to(bucket: "downsampled_data", org: "myorg")
</code></pre>

<hr />

<h2 id="influxql-sql-유사-문법-호환-모드">InfluxQL (SQL 유사 문법, 호환 모드)</h2>

<p>InfluxDB 2.x에서도 InfluxQL을 사용할 수 있습니다 (1.x 호환).</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">-- 기본 조회</span>
<span class="k">SELECT</span> <span class="n">usage_user</span> <span class="k">FROM</span> <span class="n">cpu</span> <span class="k">WHERE</span> <span class="k">host</span> <span class="o">=</span> <span class="s1">'server01'</span> <span class="k">AND</span> <span class="nb">time</span> <span class="o">&gt;</span> <span class="n">now</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</span><span class="n">h</span>

<span class="c1">-- 집계</span>
<span class="k">SELECT</span> <span class="n">MEAN</span><span class="p">(</span><span class="n">usage_user</span><span class="p">)</span> <span class="k">FROM</span> <span class="n">cpu</span> <span class="k">WHERE</span> <span class="nb">time</span> <span class="o">&gt;</span> <span class="n">now</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</span><span class="n">h</span> <span class="k">GROUP</span> <span class="k">BY</span> <span class="nb">time</span><span class="p">(</span><span class="mi">5</span><span class="n">m</span><span class="p">),</span> <span class="k">host</span>

<span class="c1">-- 최근 값</span>
<span class="k">SELECT</span> <span class="k">LAST</span><span class="p">(</span><span class="n">usage_user</span><span class="p">)</span> <span class="k">FROM</span> <span class="n">cpu</span> <span class="k">GROUP</span> <span class="k">BY</span> <span class="k">host</span>
</code></pre></div></div>

<h3 id="flux-vs-influxql-비교">Flux vs InfluxQL 비교</h3>

<table>
  <thead>
    <tr>
      <th>항목</th>
      <th>Flux</th>
      <th>InfluxQL</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>문법 스타일</td>
      <td>함수형 파이프라인</td>
      <td>SQL 유사</td>
    </tr>
    <tr>
      <td>기능 범위</td>
      <td>풍부 (JOIN, 수학, 알림)</td>
      <td>제한적</td>
    </tr>
    <tr>
      <td>학습 곡선</td>
      <td>높음</td>
      <td>낮음 (SQL 경험자)</td>
    </tr>
    <tr>
      <td>크로스 버킷 쿼리</td>
      <td>가능</td>
      <td>불가</td>
    </tr>
    <tr>
      <td>권장</td>
      <td>InfluxDB 2.x 기본</td>
      <td>마이그레이션/호환</td>
    </tr>
  </tbody>
</table>

<p><span class="nav__sub-title">관련된 글 (influxdb &gt; lecture-influxdb)</span></p>
<ul>

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-06-admin-troubleshooting/">[InfluxDB] 06. 운영 관리와 Troubleshooting</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-05-task-alert/">[InfluxDB] 05. Task, 다운샘플링, 알림</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-04-telegraf/">[InfluxDB] 04. Telegraf (데이터 수집 에이전트)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-03-flux-query/">[InfluxDB] 03. Flux 쿼리 언어</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-02-data-model/">[InfluxDB] 02. 데이터 모델 (Measurement, Tag, Field)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-01-intro/">[InfluxDB] 01. InfluxDB 소개 및 설치</a></li>
             
        
      

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

</ul>]]></content><author><name>devjaedol</name></author><category term="influxdb" /><category term="influxdb" /><category term="timeseries" /><category term="influxdb강좌" /><category term="초급" /><category term="lecture-influxdb" /><summary type="html"><![CDATA[InfluxDB 2.x의 쿼리 언어인 Flux의 기본 문법과 주요 함수를 정리합니다.]]></summary></entry><entry><title type="html">[InfluxDB] 04. Telegraf (데이터 수집 에이전트)</title><link href="https://kimjaehyun.co.kr/influxdb/influxdb-04-telegraf/" rel="alternate" type="text/html" title="[InfluxDB] 04. Telegraf (데이터 수집 에이전트)" /><published>2026-05-05T00:00:00+00:00</published><updated>2026-05-05T00:00:00+00:00</updated><id>https://kimjaehyun.co.kr/influxdb/influxdb-04-telegraf</id><content type="html" xml:base="https://kimjaehyun.co.kr/influxdb/influxdb-04-telegraf/"><![CDATA[<p>InfluxDB의 공식 데이터 수집 에이전트인 Telegraf의 설정과 활용을 정리합니다.</p>

<h1 id="telegraf란">Telegraf란?</h1>

<p>Telegraf는 InfluxData에서 개발한 플러그인 기반 메트릭 수집 에이전트입니다.  <br />
200개 이상의 입력/출력 플러그인을 지원하며, 시스템 메트릭, 애플리케이션 메트릭, 로그 등을 수집하여 InfluxDB에 전송합니다.</p>

<h2 id="아키텍처">아키텍처</h2>
<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Input Plugins] → [Processor Plugins] → [Aggregator Plugins] → [Output Plugins]
  (데이터 수집)      (데이터 변환)          (데이터 집계)          (데이터 전송)
</code></pre></div></div>

<hr />

<h2 id="설치">설치</h2>

<h3 id="linux">Linux</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install </span>telegraf
<span class="c"># 또는</span>
wget https://dl.influxdata.com/telegraf/releases/telegraf_1.x.x_amd64.deb
<span class="nb">sudo </span>dpkg <span class="nt">-i</span> telegraf_1.x.x_amd64.deb
</code></pre></div></div>

<h3 id="mac">Mac</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>brew <span class="nb">install </span>telegraf
</code></pre></div></div>

<h3 id="docker">Docker</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run <span class="nt">-d</span> <span class="nt">--name</span> telegraf <span class="se">\</span>
  <span class="nt">-v</span> /path/to/telegraf.conf:/etc/telegraf/telegraf.conf:ro <span class="se">\</span>
  telegraf
</code></pre></div></div>

<hr />

<h2 id="설정-파일-telegrafconf">설정 파일 (telegraf.conf)</h2>

<h3 id="기본-구조">기본 구조</h3>
<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 글로벌 설정</span>
<span class="k">[</span><span class="n">agent</span><span class="k">]</span>
  <span class="n">interval</span> <span class="o">=</span><span class="w"> </span><span class="s">"10s"</span>              <span class="c"># 수집 간격</span>
  <span class="n">round_interval</span> <span class="o">=</span><span class="w"> </span><span class="kc">true</span>
  <span class="n">flush_interval</span> <span class="o">=</span><span class="w"> </span><span class="s">"10s"</span>        <span class="c"># 전송 간격</span>
  <span class="n">flush_jitter</span> <span class="o">=</span><span class="w"> </span><span class="s">"0s"</span>

<span class="c"># 출력: InfluxDB 2.x</span>
<span class="k">[[</span><span class="n">outputs</span><span class="k">.</span><span class="n">influxdb_v2</span><span class="k">]]</span>
  <span class="n">urls</span> <span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s">"http://localhost:8086"</span><span class="p">]</span>
  <span class="n">token</span> <span class="o">=</span><span class="w"> </span><span class="s">"my-super-secret-token"</span>
  <span class="n">organization</span> <span class="o">=</span><span class="w"> </span><span class="s">"myorg"</span>
  <span class="n">bucket</span> <span class="o">=</span><span class="w"> </span><span class="s">"mybucket"</span>

<span class="c"># 입력: CPU</span>
<span class="k">[[</span><span class="n">inputs</span><span class="k">.</span><span class="n">cpu</span><span class="k">]]</span>
  <span class="n">percpu</span> <span class="o">=</span><span class="w"> </span><span class="kc">true</span>
  <span class="n">totalcpu</span> <span class="o">=</span><span class="w"> </span><span class="kc">true</span>
  <span class="n">collect_cpu_time</span> <span class="o">=</span><span class="w"> </span><span class="kc">false</span>

<span class="c"># 입력: 메모리</span>
<span class="k">[[</span><span class="n">inputs</span><span class="k">.</span><span class="n">mem</span><span class="k">]]</span>

<span class="c"># 입력: 디스크</span>
<span class="k">[[</span><span class="n">inputs</span><span class="k">.</span><span class="n">disk</span><span class="k">]]</span>
  <span class="n">ignore_fs</span> <span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s">"tmpfs"</span><span class="p">,</span> <span class="s">"devtmpfs"</span><span class="p">]</span>

<span class="c"># 입력: 네트워크</span>
<span class="k">[[</span><span class="n">inputs</span><span class="k">.</span><span class="n">net</span><span class="k">]]</span>
</code></pre></div></div>

<hr />

<h2 id="주요-input-플러그인">주요 Input 플러그인</h2>

<h3 id="시스템-메트릭">시스템 메트릭</h3>

<table>
  <thead>
    <tr>
      <th>플러그인</th>
      <th>수집 항목</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.cpu</code></td>
      <td>CPU 사용률</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.mem</code></td>
      <td>메모리 사용량</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.disk</code></td>
      <td>디스크 사용량</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.diskio</code></td>
      <td>디스크 I/O</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.net</code></td>
      <td>네트워크 트래픽</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.system</code></td>
      <td>부하, 가동 시간</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.processes</code></td>
      <td>프로세스 수</td>
    </tr>
  </tbody>
</table>

<h3 id="애플리케이션서비스">애플리케이션/서비스</h3>

<table>
  <thead>
    <tr>
      <th>플러그인</th>
      <th>대상</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.nginx</code></td>
      <td>Nginx 상태</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.apache</code></td>
      <td>Apache 상태</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.mysql</code></td>
      <td>MySQL 메트릭</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.postgresql</code></td>
      <td>PostgreSQL 메트릭</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.redis</code></td>
      <td>Redis 메트릭</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.mongodb</code></td>
      <td>MongoDB 메트릭</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.docker</code></td>
      <td>Docker 컨테이너</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.kubernetes</code></td>
      <td>Kubernetes 메트릭</td>
    </tr>
  </tbody>
</table>

<h3 id="기타">기타</h3>

<table>
  <thead>
    <tr>
      <th>플러그인</th>
      <th>용도</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.http_response</code></td>
      <td>HTTP 엔드포인트 모니터링</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.ping</code></td>
      <td>네트워크 연결 확인</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.snmp</code></td>
      <td>SNMP 장비 모니터링</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.mqtt_consumer</code></td>
      <td>MQTT 메시지 수집</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.tail</code></td>
      <td>로그 파일 추적</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">inputs.exec</code></td>
      <td>커스텀 스크립트 실행</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="설정-예시">설정 예시</h2>

<h3 id="mysql-모니터링">MySQL 모니터링</h3>
<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">[[</span><span class="n">inputs</span><span class="k">.</span><span class="n">mysql</span><span class="k">]]</span>
  <span class="n">servers</span> <span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s">"user:password@tcp(localhost:3306)/"</span><span class="p">]</span>
  <span class="n">gather_table_schema</span> <span class="o">=</span><span class="w"> </span><span class="kc">true</span>
  <span class="n">gather_process_list</span> <span class="o">=</span><span class="w"> </span><span class="kc">true</span>
  <span class="n">gather_slave_status</span> <span class="o">=</span><span class="w"> </span><span class="kc">true</span>
</code></pre></div></div>

<h3 id="docker-모니터링">Docker 모니터링</h3>
<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">[[</span><span class="n">inputs</span><span class="k">.</span><span class="n">docker</span><span class="k">]]</span>
  <span class="n">endpoint</span> <span class="o">=</span><span class="w"> </span><span class="s">"unix:///var/run/docker.sock"</span>
  <span class="n">container_names</span> <span class="o">=</span><span class="w"> </span><span class="p">[]</span>
  <span class="n">timeout</span> <span class="o">=</span><span class="w"> </span><span class="s">"5s"</span>
  <span class="n">perdevice</span> <span class="o">=</span><span class="w"> </span><span class="kc">true</span>
  <span class="n">total</span> <span class="o">=</span><span class="w"> </span><span class="kc">true</span>
</code></pre></div></div>

<h3 id="http-엔드포인트-체크">HTTP 엔드포인트 체크</h3>
<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">[[</span><span class="n">inputs</span><span class="k">.</span><span class="n">http_response</span><span class="k">]]</span>
  <span class="n">urls</span> <span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s">"https://myapp.com/health"</span><span class="p">,</span> <span class="s">"https://api.myapp.com/status"</span><span class="p">]</span>
  <span class="n">response_timeout</span> <span class="o">=</span><span class="w"> </span><span class="s">"5s"</span>
  <span class="n">method</span> <span class="o">=</span><span class="w"> </span><span class="s">"GET"</span>
  <span class="n">follow_redirects</span> <span class="o">=</span><span class="w"> </span><span class="kc">true</span>
</code></pre></div></div>

<h3 id="커스텀-스크립트">커스텀 스크립트</h3>
<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">[[</span><span class="n">inputs</span><span class="k">.</span><span class="n">exec</span><span class="k">]]</span>
  <span class="n">commands</span> <span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s">"/opt/scripts/custom_metric.sh"</span><span class="p">]</span>
  <span class="n">timeout</span> <span class="o">=</span><span class="w"> </span><span class="s">"5s"</span>
  <span class="n">data_format</span> <span class="o">=</span><span class="w"> </span><span class="s">"influx"</span>    <span class="c"># Line Protocol 형식 출력</span>
</code></pre></div></div>

<hr />

<h2 id="실행-및-관리">실행 및 관리</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 설정 파일 테스트</span>
telegraf <span class="nt">--config</span> telegraf.conf <span class="nt">--test</span>

<span class="c"># 포그라운드 실행</span>
telegraf <span class="nt">--config</span> telegraf.conf

<span class="c"># 서비스 시작</span>
<span class="nb">sudo </span>systemctl start telegraf
<span class="nb">sudo </span>systemctl <span class="nb">enable </span>telegraf

<span class="c"># 로그 확인</span>
<span class="nb">sudo </span>journalctl <span class="nt">-u</span> telegraf <span class="nt">-f</span>
</code></pre></div></div>

<hr />

<h2 id="telegraf--grafana--influxdb-연동-구성">Telegraf + Grafana + InfluxDB 연동 구성</h2>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[서버/앱] → [Telegraf] → [InfluxDB] → [Grafana 대시보드]
</code></pre></div></div>

<p>이 구성은 서버 모니터링의 가장 일반적인 오픈소스 스택입니다.</p>

<table>
  <thead>
    <tr>
      <th>단계</th>
      <th>역할</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Telegraf</td>
      <td>10초마다 시스템 메트릭 수집 → InfluxDB 전송</td>
    </tr>
    <tr>
      <td>InfluxDB</td>
      <td>시계열 데이터 저장, 30일 보존</td>
    </tr>
    <tr>
      <td>Grafana</td>
      <td>InfluxDB를 데이터 소스로 대시보드 시각화</td>
    </tr>
  </tbody>
</table>

<p><span class="nav__sub-title">관련된 글 (influxdb &gt; lecture-influxdb)</span></p>
<ul>

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-06-admin-troubleshooting/">[InfluxDB] 06. 운영 관리와 Troubleshooting</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-05-task-alert/">[InfluxDB] 05. Task, 다운샘플링, 알림</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-04-telegraf/">[InfluxDB] 04. Telegraf (데이터 수집 에이전트)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-03-flux-query/">[InfluxDB] 03. Flux 쿼리 언어</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-02-data-model/">[InfluxDB] 02. 데이터 모델 (Measurement, Tag, Field)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-01-intro/">[InfluxDB] 01. InfluxDB 소개 및 설치</a></li>
             
        
      

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

</ul>]]></content><author><name>devjaedol</name></author><category term="influxdb" /><category term="influxdb" /><category term="timeseries" /><category term="telegraf" /><category term="influxdb강좌" /><category term="중급" /><category term="lecture-influxdb" /><summary type="html"><![CDATA[InfluxDB의 공식 데이터 수집 에이전트인 Telegraf의 설정과 활용을 정리합니다.]]></summary></entry><entry><title type="html">[InfluxDB] 05. Task, 다운샘플링, 알림</title><link href="https://kimjaehyun.co.kr/influxdb/influxdb-05-task-alert/" rel="alternate" type="text/html" title="[InfluxDB] 05. Task, 다운샘플링, 알림" /><published>2026-05-05T00:00:00+00:00</published><updated>2026-05-05T00:00:00+00:00</updated><id>https://kimjaehyun.co.kr/influxdb/influxdb-05-task-alert</id><content type="html" xml:base="https://kimjaehyun.co.kr/influxdb/influxdb-05-task-alert/"><![CDATA[<p>InfluxDB의 Task(예약 작업), 다운샘플링, 알림(Alert) 설정을 정리합니다.</p>

<h1 id="task-예약-작업">Task (예약 작업)</h1>

<p>Task는 Flux 스크립트를 주기적으로 실행하는 예약 작업입니다.  <br />
다운샘플링, 데이터 변환, 알림 등에 활용됩니다.</p>

<h2 id="task-생성">Task 생성</h2>

<h3 id="웹-ui에서-생성">웹 UI에서 생성</h3>
<p>InfluxDB 웹 UI → Tasks → Create Task</p>

<h3 id="flux-스크립트로-생성">Flux 스크립트로 생성</h3>
<pre><code class="language-flux">option task = {
    name: "downsample_cpu_hourly",
    every: 1h,
    offset: 5m    // 데이터 지연 고려 (5분 후 실행)
}

from(bucket: "raw_metrics")
  |&gt; range(start: -task.every)
  |&gt; filter(fn: (r) =&gt; r._measurement == "cpu")
  |&gt; aggregateWindow(every: 1h, fn: mean, createEmpty: false)
  |&gt; to(bucket: "downsampled_metrics", org: "myorg")
</code></pre>

<h3 id="task-옵션">Task 옵션</h3>

<table>
  <thead>
    <tr>
      <th>옵션</th>
      <th>설명</th>
      <th>예시</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">name</code></td>
      <td>작업 이름</td>
      <td><code class="language-plaintext highlighter-rouge">"downsample_cpu"</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">every</code></td>
      <td>실행 간격</td>
      <td><code class="language-plaintext highlighter-rouge">1h</code>, <code class="language-plaintext highlighter-rouge">5m</code>, <code class="language-plaintext highlighter-rouge">1d</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">cron</code></td>
      <td>Cron 표현식</td>
      <td><code class="language-plaintext highlighter-rouge">"0 * * * *"</code> (매시 정각)</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">offset</code></td>
      <td>실행 지연</td>
      <td><code class="language-plaintext highlighter-rouge">5m</code> (데이터 도착 대기)</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="다운샘플링-downsampling">다운샘플링 (Downsampling)</h2>

<p>원본 데이터를 요약하여 저장 공간을 절약하고 장기 조회 성능을 향상시킵니다.</p>

<h3 id="전략-예시">전략 예시</h3>

<table>
  <thead>
    <tr>
      <th>보존 기간</th>
      <th>해상도</th>
      <th>버킷</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>7일</td>
      <td>원본 (10초)</td>
      <td>raw_metrics</td>
    </tr>
    <tr>
      <td>30일</td>
      <td>5분 평균</td>
      <td>metrics_5m</td>
    </tr>
    <tr>
      <td>1년</td>
      <td>1시간 평균</td>
      <td>metrics_1h</td>
    </tr>
    <tr>
      <td>무기한</td>
      <td>1일 평균</td>
      <td>metrics_1d</td>
    </tr>
  </tbody>
</table>

<h3 id="다운샘플링-task-예시">다운샘플링 Task 예시</h3>
<pre><code class="language-flux">// 5분 평균으로 다운샘플링
option task = { name: "downsample_5m", every: 5m, offset: 30s }

from(bucket: "raw_metrics")
  |&gt; range(start: -task.every)
  |&gt; filter(fn: (r) =&gt; r._measurement == "cpu" or r._measurement == "memory")
  |&gt; aggregateWindow(every: 5m, fn: mean, createEmpty: false)
  |&gt; to(bucket: "metrics_5m", org: "myorg")
</code></pre>

<pre><code class="language-flux">// 1시간 평균 + 최대값 다운샘플링
option task = { name: "downsample_1h", every: 1h, offset: 5m }

data = from(bucket: "metrics_5m")
  |&gt; range(start: -task.every)
  |&gt; filter(fn: (r) =&gt; r._measurement == "cpu")

// 평균
data |&gt; aggregateWindow(every: 1h, fn: mean) |&gt; to(bucket: "metrics_1h_avg")

// 최대값
data |&gt; aggregateWindow(every: 1h, fn: max) |&gt; to(bucket: "metrics_1h_max")
</code></pre>

<hr />

<h2 id="알림-alert--check">알림 (Alert / Check)</h2>

<p>InfluxDB 2.x는 내장 알림 기능을 제공합니다.</p>

<h3 id="구성-요소">구성 요소</h3>

<table>
  <thead>
    <tr>
      <th>구성 요소</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Check</td>
      <td>데이터를 주기적으로 확인하고 상태 판단</td>
    </tr>
    <tr>
      <td>Notification Rule</td>
      <td>상태 변경 시 알림 전송 규칙</td>
    </tr>
    <tr>
      <td>Notification Endpoint</td>
      <td>알림 수신 대상 (Slack, Email, PagerDuty 등)</td>
    </tr>
  </tbody>
</table>

<h3 id="check-종류">Check 종류</h3>

<table>
  <thead>
    <tr>
      <th>종류</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Threshold Check</td>
      <td>임계값 기반 (값 &gt; 90이면 CRIT)</td>
    </tr>
    <tr>
      <td>Deadman Check</td>
      <td>데이터 미수신 감지 (10분간 데이터 없으면 알림)</td>
    </tr>
  </tbody>
</table>

<h3 id="threshold-check-예시-flux">Threshold Check 예시 (Flux)</h3>
<pre><code class="language-flux">import "influxdata/influxdb/monitor"

option task = { name: "cpu_alert", every: 1m }

data = from(bucket: "mybucket")
  |&gt; range(start: -5m)
  |&gt; filter(fn: (r) =&gt; r._measurement == "cpu" and r._field == "usage_user")
  |&gt; aggregateWindow(every: 1m, fn: mean)

data
  |&gt; monitor.check(
      crit: (r) =&gt; r._value &gt; 90.0,
      warn: (r) =&gt; r._value &gt; 70.0,
      info: (r) =&gt; r._value &gt; 50.0,
      ok: (r) =&gt; r._value &lt;= 50.0,
      messageFn: (r) =&gt; "CPU 사용률: ${string(v: r._value)}% on ${r.host}"
  )
</code></pre>

<h3 id="deadman-check-데이터-미수신-감지">Deadman Check (데이터 미수신 감지)</h3>
<pre><code class="language-flux">import "influxdata/influxdb/monitor"

option task = { name: "deadman_check", every: 5m }

from(bucket: "mybucket")
  |&gt; range(start: -10m)
  |&gt; filter(fn: (r) =&gt; r._measurement == "heartbeat")
  |&gt; monitor.deadman(t: -5m)
</code></pre>

<hr />

<h2 id="notification-endpoint-설정">Notification Endpoint 설정</h2>

<h3 id="slack">Slack</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>influx notification-endpoint create <span class="se">\</span>
  <span class="nt">--name</span> slack-alerts <span class="se">\</span>
  <span class="nt">--type</span> slack <span class="se">\</span>
  <span class="nt">--url</span> <span class="s2">"https://hooks.slack.com/services/T00/B00/xxx"</span>
</code></pre></div></div>

<h3 id="webhook-범용">Webhook (범용)</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>influx notification-endpoint create <span class="se">\</span>
  <span class="nt">--name</span> webhook-alerts <span class="se">\</span>
  <span class="nt">--type</span> http <span class="se">\</span>
  <span class="nt">--url</span> <span class="s2">"https://myapp.com/webhook/alerts"</span> <span class="se">\</span>
  <span class="nt">--method</span> POST
</code></pre></div></div>

<hr />

<h2 id="task-관리">Task 관리</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Task 목록</span>
influx task list

<span class="c"># Task 실행 이력</span>
influx task log list <span class="nt">--task-id</span> &lt;task-id&gt;

<span class="c"># Task 비활성화/활성화</span>
influx task update <span class="nt">--id</span> &lt;task-id&gt; <span class="nt">--status</span> inactive
influx task update <span class="nt">--id</span> &lt;task-id&gt; <span class="nt">--status</span> active

<span class="c"># Task 삭제</span>
influx task delete <span class="nt">--id</span> &lt;task-id&gt;

<span class="c"># 수동 실행</span>
influx task retry-failed <span class="nt">--id</span> &lt;task-id&gt;
</code></pre></div></div>

<p><span class="nav__sub-title">관련된 글 (influxdb &gt; lecture-influxdb)</span></p>
<ul>

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-06-admin-troubleshooting/">[InfluxDB] 06. 운영 관리와 Troubleshooting</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-05-task-alert/">[InfluxDB] 05. Task, 다운샘플링, 알림</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-04-telegraf/">[InfluxDB] 04. Telegraf (데이터 수집 에이전트)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-03-flux-query/">[InfluxDB] 03. Flux 쿼리 언어</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-02-data-model/">[InfluxDB] 02. 데이터 모델 (Measurement, Tag, Field)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-01-intro/">[InfluxDB] 01. InfluxDB 소개 및 설치</a></li>
             
        
      

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

</ul>]]></content><author><name>devjaedol</name></author><category term="influxdb" /><category term="influxdb" /><category term="timeseries" /><category term="influxdb강좌" /><category term="중급" /><category term="lecture-influxdb" /><summary type="html"><![CDATA[InfluxDB의 Task(예약 작업), 다운샘플링, 알림(Alert) 설정을 정리합니다.]]></summary></entry><entry><title type="html">[InfluxDB] 06. 운영 관리와 Troubleshooting</title><link href="https://kimjaehyun.co.kr/influxdb/influxdb-06-admin-troubleshooting/" rel="alternate" type="text/html" title="[InfluxDB] 06. 운영 관리와 Troubleshooting" /><published>2026-05-05T00:00:00+00:00</published><updated>2026-05-05T00:00:00+00:00</updated><id>https://kimjaehyun.co.kr/influxdb/influxdb-06-admin-troubleshooting</id><content type="html" xml:base="https://kimjaehyun.co.kr/influxdb/influxdb-06-admin-troubleshooting/"><![CDATA[<p>InfluxDB의 운영 관리, 백업/복구, 성능 튜닝, 자주 발생하는 문제 해결을 정리합니다.</p>

<h1 id="보안-및-인증">보안 및 인증</h1>

<h2 id="토큰-관리">토큰 관리</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 토큰 목록</span>
influx auth list

<span class="c"># 읽기 전용 토큰 생성</span>
influx auth create <span class="se">\</span>
  <span class="nt">--org</span> myorg <span class="se">\</span>
  <span class="nt">--read-bucket</span> mybucket <span class="se">\</span>
  <span class="nt">--description</span> <span class="s2">"Grafana read-only"</span>

<span class="c"># 읽기/쓰기 토큰 생성</span>
influx auth create <span class="se">\</span>
  <span class="nt">--org</span> myorg <span class="se">\</span>
  <span class="nt">--read-bucket</span> mybucket <span class="se">\</span>
  <span class="nt">--write-bucket</span> mybucket <span class="se">\</span>
  <span class="nt">--description</span> <span class="s2">"Telegraf write"</span>

<span class="c"># 토큰 비활성화</span>
influx auth inactive <span class="nt">--id</span> &lt;token-id&gt;

<span class="c"># 토큰 삭제</span>
influx auth delete <span class="nt">--id</span> &lt;token-id&gt;
</code></pre></div></div>

<h2 id="사용자-관리">사용자 관리</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 사용자 생성</span>
influx user create <span class="nt">--name</span> devuser <span class="nt">--org</span> myorg

<span class="c"># 비밀번호 설정</span>
influx user password <span class="nt">--name</span> devuser

<span class="c"># 사용자 목록</span>
influx user list

<span class="c"># 사용자 삭제</span>
influx user delete <span class="nt">--name</span> devuser
</code></pre></div></div>

<hr />

<h2 id="백업과-복구">백업과 복구</h2>

<h3 id="백업">백업</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 전체 백업</span>
influx backup /backup/influxdb/full_<span class="si">$(</span><span class="nb">date</span> +%Y%m%d<span class="si">)</span>

<span class="c"># 특정 버킷만</span>
influx backup /backup/influxdb/mybucket <span class="nt">--bucket</span> mybucket

<span class="c"># 압축 백업</span>
influx backup /backup/influxdb/backup_<span class="si">$(</span><span class="nb">date</span> +%Y%m%d<span class="si">)</span> <span class="nt">--compression</span> <span class="nb">gzip</span>
</code></pre></div></div>

<h3 id="복구">복구</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 전체 복구</span>
influx restore /backup/influxdb/full_20260505

<span class="c"># 특정 버킷 복구</span>
influx restore /backup/influxdb/mybucket <span class="nt">--bucket</span> mybucket

<span class="c"># 다른 이름으로 복구</span>
influx restore /backup/influxdb/mybucket <span class="nt">--bucket</span> mybucket <span class="nt">--new-bucket</span> mybucket_restored
</code></pre></div></div>

<hr />

<h2 id="성능-튜닝">성능 튜닝</h2>

<h3 id="시리즈-카디널리티-관리">시리즈 카디널리티 관리</h3>

<p>시리즈 카디널리티는 InfluxDB 성능의 가장 중요한 지표입니다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 시리즈 카디널리티 확인</span>
influx query <span class="s1">'import "influxdata/influxdb"
influxdb.cardinality(bucket: "mybucket", start: -30d)'</span>
</code></pre></div></div>

<pre><code class="language-flux">// 측정별 시리즈 수 확인
import "influxdata/influxdb"

influxdb.cardinality(bucket: "mybucket", start: -30d)
  |&gt; group(columns: ["_measurement"])
  |&gt; count()
</code></pre>

<h3 id="카디널리티-줄이기">카디널리티 줄이기</h3>

<table>
  <thead>
    <tr>
      <th>방법</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>높은 카디널리티 Tag 제거</td>
      <td>user_id, request_id 등을 Field로 변경</td>
    </tr>
    <tr>
      <td>Tag 값 정규화</td>
      <td>URL 경로를 패턴으로 그룹핑</td>
    </tr>
    <tr>
      <td>불필요한 Tag 제거</td>
      <td>사용하지 않는 Tag 삭제</td>
    </tr>
    <tr>
      <td>버킷 분리</td>
      <td>용도별 버킷 분리</td>
    </tr>
  </tbody>
</table>

<h3 id="스토리지-설정-configtoml">스토리지 설정 (config.toml)</h3>
<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">[</span><span class="n">storage</span><span class="k">]</span>
  <span class="c"># TSM 엔진 캐시 크기</span>
  <span class="n">cache-max-memory-size</span> <span class="o">=</span><span class="w"> </span><span class="s">"1g"</span>
  
  <span class="c"># 캐시 스냅샷 크기</span>
  <span class="n">cache-snapshot-memory-size</span> <span class="o">=</span><span class="w"> </span><span class="s">"25m"</span>
  
  <span class="c"># 컴팩션 처리량</span>
  <span class="n">compact-throughput</span> <span class="o">=</span><span class="w"> </span><span class="s">"48m"</span>
  <span class="n">compact-throughput-burst</span> <span class="o">=</span><span class="w"> </span><span class="s">"48m"</span>
</code></pre></div></div>

<h3 id="쿼리-최적화">쿼리 최적화</h3>

<pre><code class="language-flux">// ❌ 넓은 시간 범위 + 필터 없음
from(bucket: "mybucket")
  |&gt; range(start: -30d)

// ✅ 좁은 시간 범위 + 구체적 필터
from(bucket: "mybucket")
  |&gt; range(start: -1h)
  |&gt; filter(fn: (r) =&gt; r._measurement == "cpu" and r.host == "server01")
  |&gt; filter(fn: (r) =&gt; r._field == "usage_user")

// ❌ 불필요한 데이터 로드 후 제거
from(bucket: "mybucket")
  |&gt; range(start: -1h)
  |&gt; last()

// ✅ pushdown 최적화 (filter를 먼저)
from(bucket: "mybucket")
  |&gt; range(start: -1h)
  |&gt; filter(fn: (r) =&gt; r._measurement == "cpu")
  |&gt; last()
</code></pre>

<hr />

<h2 id="모니터링">모니터링</h2>

<h3 id="내부-메트릭-확인">내부 메트릭 확인</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># /metrics 엔드포인트 (Prometheus 형식)</span>
curl http://localhost:8086/metrics

<span class="c"># 주요 지표</span>
<span class="c"># influxdb_organizations_total</span>
<span class="c"># influxdb_buckets_total</span>
<span class="c"># influxdb_series_total (시리즈 카디널리티)</span>
<span class="c"># go_memstats_alloc_bytes (메모리 사용량)</span>
<span class="c"># http_api_requests_total (API 요청 수)</span>
</code></pre></div></div>

<h3 id="디스크-사용량-확인">디스크 사용량 확인</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 데이터 디렉토리 크기</span>
<span class="nb">du</span> <span class="nt">-sh</span> /var/lib/influxdb2/engine/

<span class="c"># 버킷별 크기</span>
<span class="nb">du</span> <span class="nt">-sh</span> /var/lib/influxdb2/engine/data/<span class="k">*</span>
</code></pre></div></div>

<hr />

<h2 id="자주-발생하는-문제">자주 발생하는 문제</h2>

<h3 id="1-높은-시리즈-카디널리티로-인한-성능-저하">1. 높은 시리즈 카디널리티로 인한 성능 저하</h3>

<p>증상: 메모리 사용량 급증, 쿼리 느려짐, OOM</p>

<pre><code class="language-flux">// 카디널리티 확인
import "influxdata/influxdb"
influxdb.cardinality(bucket: "mybucket", start: -7d)
</code></pre>

<table>
  <thead>
    <tr>
      <th>해결</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>높은 카디널리티 Tag → Field 변경</td>
      <td>스키마 재설계</td>
    </tr>
    <tr>
      <td>불필요한 시리즈 삭제</td>
      <td><code class="language-plaintext highlighter-rouge">influx delete</code></td>
    </tr>
    <tr>
      <td>버킷 보존 기간 단축</td>
      <td>오래된 데이터 자동 삭제</td>
    </tr>
  </tbody>
</table>

<h3 id="2-디스크-용량-부족">2. 디스크 용량 부족</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 데이터 삭제 (시간 범위)</span>
influx delete <span class="se">\</span>
  <span class="nt">--bucket</span> mybucket <span class="se">\</span>
  <span class="nt">--start</span> 2025-01-01T00:00:00Z <span class="se">\</span>
  <span class="nt">--stop</span> 2025-06-01T00:00:00Z

<span class="c"># 특정 measurement 삭제</span>
influx delete <span class="se">\</span>
  <span class="nt">--bucket</span> mybucket <span class="se">\</span>
  <span class="nt">--start</span> 1970-01-01T00:00:00Z <span class="se">\</span>
  <span class="nt">--stop</span> <span class="si">$(</span><span class="nb">date</span> <span class="nt">-u</span> +<span class="s2">"%Y-%m-%dT%H:%M:%SZ"</span><span class="si">)</span> <span class="se">\</span>
  <span class="nt">--predicate</span> <span class="s1">'_measurement="old_metric"'</span>
</code></pre></div></div>

<h3 id="3-쓰기-실패-write-timeout">3. 쓰기 실패 (Write Timeout)</h3>

<table>
  <thead>
    <tr>
      <th>원인</th>
      <th>해결</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>배치 크기 과대</td>
      <td>배치 크기 줄이기 (5000 포인트 이하)</td>
    </tr>
    <tr>
      <td>디스크 I/O 병목</td>
      <td>SSD 사용, I/O 스케줄러 확인</td>
    </tr>
    <tr>
      <td>카디널리티 폭발</td>
      <td>Tag 설계 검토</td>
    </tr>
  </tbody>
</table>

<h3 id="4-쿼리-타임아웃">4. 쿼리 타임아웃</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 쿼리 타임아웃 설정 (config.toml)</span>
<span class="c"># query-timeout = "30s"</span>
</code></pre></div></div>

<table>
  <thead>
    <tr>
      <th>해결</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>시간 범위 축소</td>
      <td>조회 기간 줄이기</td>
    </tr>
    <tr>
      <td>다운샘플링 활용</td>
      <td>장기 조회는 요약 버킷 사용</td>
    </tr>
    <tr>
      <td>필터 추가</td>
      <td>measurement, tag 필터 구체화</td>
    </tr>
    <tr>
      <td>aggregateWindow 사용</td>
      <td>원본 대신 집계 데이터 조회</td>
    </tr>
  </tbody>
</table>

<h3 id="5-telegraf-데이터-미수신">5. Telegraf 데이터 미수신</h3>

<table>
  <thead>
    <tr>
      <th>확인 항목</th>
      <th>방법</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Telegraf 실행 상태</td>
      <td><code class="language-plaintext highlighter-rouge">systemctl status telegraf</code></td>
    </tr>
    <tr>
      <td>설정 파일 오류</td>
      <td><code class="language-plaintext highlighter-rouge">telegraf --config telegraf.conf --test</code></td>
    </tr>
    <tr>
      <td>토큰 권한</td>
      <td>쓰기 권한 있는 토큰인지 확인</td>
    </tr>
    <tr>
      <td>네트워크</td>
      <td>InfluxDB 포트 접근 가능 여부</td>
    </tr>
    <tr>
      <td>로그 확인</td>
      <td><code class="language-plaintext highlighter-rouge">journalctl -u telegraf -f</code></td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="운영-체크리스트">운영 체크리스트</h2>

<table>
  <thead>
    <tr>
      <th>항목</th>
      <th>확인 방법</th>
      <th>권장</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>시리즈 카디널리티</td>
      <td><code class="language-plaintext highlighter-rouge">influxdb.cardinality()</code></td>
      <td>100만 이하 (OSS)</td>
    </tr>
    <tr>
      <td>디스크 사용량</td>
      <td><code class="language-plaintext highlighter-rouge">du -sh</code></td>
      <td>여유 공간 20% 이상</td>
    </tr>
    <tr>
      <td>메모리 사용량</td>
      <td><code class="language-plaintext highlighter-rouge">/metrics</code></td>
      <td>물리 메모리의 80% 이하</td>
    </tr>
    <tr>
      <td>보존 정책</td>
      <td>버킷 설정 확인</td>
      <td>용도에 맞게 설정</td>
    </tr>
    <tr>
      <td>다운샘플링</td>
      <td>Task 실행 상태</td>
      <td>장기 데이터 요약</td>
    </tr>
    <tr>
      <td>백업</td>
      <td>정기 백업 스크립트</td>
      <td>일 1회 이상</td>
    </tr>
    <tr>
      <td>토큰 관리</td>
      <td>최소 권한 원칙</td>
      <td>읽기/쓰기 분리</td>
    </tr>
    <tr>
      <td>Telegraf 상태</td>
      <td>로그 확인</td>
      <td>에러 없는지 확인</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="db-선택-가이드-최종-비교">DB 선택 가이드 (최종 비교)</h2>

<table>
  <thead>
    <tr>
      <th>요구사항</th>
      <th>추천 DB</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>시계열 메트릭 (모니터링, IoT)</td>
      <td>InfluxDB</td>
    </tr>
    <tr>
      <td>범용 관계형 데이터</td>
      <td>PostgreSQL, MySQL</td>
    </tr>
    <tr>
      <td>문서형 유연한 스키마</td>
      <td>MongoDB</td>
    </tr>
    <tr>
      <td>캐시, 세션, 실시간</td>
      <td>Redis</td>
    </tr>
    <tr>
      <td>로그 검색, 전문 검색</td>
      <td>Elasticsearch</td>
    </tr>
    <tr>
      <td>대규모 분석 (OLAP)</td>
      <td>ClickHouse, TimescaleDB</td>
    </tr>
  </tbody>
</table>

<p><span class="nav__sub-title">관련된 글 (influxdb &gt; lecture-influxdb)</span></p>
<ul>

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-06-admin-troubleshooting/">[InfluxDB] 06. 운영 관리와 Troubleshooting</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-05-task-alert/">[InfluxDB] 05. Task, 다운샘플링, 알림</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-04-telegraf/">[InfluxDB] 04. Telegraf (데이터 수집 에이전트)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-03-flux-query/">[InfluxDB] 03. Flux 쿼리 언어</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-02-data-model/">[InfluxDB] 02. 데이터 모델 (Measurement, Tag, Field)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/influxdb/influxdb-01-intro/">[InfluxDB] 01. InfluxDB 소개 및 설치</a></li>
             
        
      

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

</ul>]]></content><author><name>devjaedol</name></author><category term="influxdb" /><category term="influxdb" /><category term="timeseries" /><category term="influxdb강좌" /><category term="고급" /><category term="lecture-influxdb" /><summary type="html"><![CDATA[InfluxDB의 운영 관리, 백업/복구, 성능 튜닝, 자주 발생하는 문제 해결을 정리합니다.]]></summary></entry><entry><title type="html">[MongoDB] 01. MongoDB 소개 및 설치</title><link href="https://kimjaehyun.co.kr/mongodb/mongodb-01-intro/" rel="alternate" type="text/html" title="[MongoDB] 01. MongoDB 소개 및 설치" /><published>2026-05-05T00:00:00+00:00</published><updated>2026-05-05T00:00:00+00:00</updated><id>https://kimjaehyun.co.kr/mongodb/mongodb-01-intro</id><content type="html" xml:base="https://kimjaehyun.co.kr/mongodb/mongodb-01-intro/"><![CDATA[<p>MongoDB의 기본 개념, 특징, 설치 방법을 알아봅니다.</p>

<h1 id="mongodb란">MongoDB란?</h1>

<p>MongoDB는 문서(Document) 지향 NoSQL 데이터베이스입니다.  <br />
JSON과 유사한 BSON(Binary JSON) 형식으로 데이터를 저장하며, 유연한 스키마와 수평 확장을 제공합니다.</p>

<h2 id="rdbms-vs-mongodb-비교">RDBMS vs MongoDB 비교</h2>

<table>
  <thead>
    <tr>
      <th style="text-align: center">항목</th>
      <th style="text-align: center">RDBMS (MySQL 등)</th>
      <th style="text-align: center">MongoDB</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: center">데이터 모델</td>
      <td style="text-align: center">테이블/행/열 (관계형)</td>
      <td style="text-align: center">컬렉션/문서 (문서형)</td>
    </tr>
    <tr>
      <td style="text-align: center">스키마</td>
      <td style="text-align: center">고정 스키마 필수</td>
      <td style="text-align: center">유연한 스키마 (Schemaless)</td>
    </tr>
    <tr>
      <td style="text-align: center">데이터 형식</td>
      <td style="text-align: center">행(Row)</td>
      <td style="text-align: center">BSON 문서 (JSON 유사)</td>
    </tr>
    <tr>
      <td style="text-align: center">쿼리 언어</td>
      <td style="text-align: center">SQL</td>
      <td style="text-align: center">MQL (MongoDB Query Language)</td>
    </tr>
    <tr>
      <td style="text-align: center">JOIN</td>
      <td style="text-align: center">지원</td>
      <td style="text-align: center">$lookup (제한적), 비정규화 권장</td>
    </tr>
    <tr>
      <td style="text-align: center">트랜잭션</td>
      <td style="text-align: center">ACID 완전 지원</td>
      <td style="text-align: center">4.0+ 다중 문서 트랜잭션 지원</td>
    </tr>
    <tr>
      <td style="text-align: center">확장 방식</td>
      <td style="text-align: center">수직 확장 (Scale-Up)</td>
      <td style="text-align: center">수평 확장 (Sharding)</td>
    </tr>
    <tr>
      <td style="text-align: center">인덱스</td>
      <td style="text-align: center">B-Tree</td>
      <td style="text-align: center">B-Tree, 복합, 텍스트, 지리공간 등</td>
    </tr>
  </tbody>
</table>

<h2 id="rdbms--mongodb-용어-매핑">RDBMS ↔ MongoDB 용어 매핑</h2>

<table>
  <thead>
    <tr>
      <th>RDBMS</th>
      <th>MongoDB</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Database</td>
      <td>Database</td>
      <td>동일</td>
    </tr>
    <tr>
      <td>Table</td>
      <td>Collection</td>
      <td>문서의 그룹</td>
    </tr>
    <tr>
      <td>Row</td>
      <td>Document</td>
      <td>하나의 데이터 레코드</td>
    </tr>
    <tr>
      <td>Column</td>
      <td>Field</td>
      <td>문서 내 키-값 쌍</td>
    </tr>
    <tr>
      <td>Primary Key</td>
      <td>_id</td>
      <td>자동 생성 (ObjectId)</td>
    </tr>
    <tr>
      <td>JOIN</td>
      <td>$lookup / Embedding</td>
      <td>관계 표현</td>
    </tr>
    <tr>
      <td>Index</td>
      <td>Index</td>
      <td>동일 개념</td>
    </tr>
    <tr>
      <td>Schema</td>
      <td>Validator (선택적)</td>
      <td>유연한 스키마</td>
    </tr>
  </tbody>
</table>

<h2 id="mongodb-주요-특징">MongoDB 주요 특징</h2>

<table>
  <thead>
    <tr>
      <th>특징</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>유연한 스키마</td>
      <td>같은 컬렉션 내 문서마다 구조가 달라도 됨</td>
    </tr>
    <tr>
      <td>중첩 문서</td>
      <td>문서 안에 문서를 포함 (Embedded Document)</td>
    </tr>
    <tr>
      <td>배열 지원</td>
      <td>필드 값으로 배열 저장 가능</td>
    </tr>
    <tr>
      <td>수평 확장</td>
      <td>Sharding으로 데이터 분산</td>
    </tr>
    <tr>
      <td>복제</td>
      <td>Replica Set으로 고가용성</td>
    </tr>
    <tr>
      <td>풍부한 쿼리</td>
      <td>범위, 정규식, 배열, 지리공간 쿼리</td>
    </tr>
    <tr>
      <td>Aggregation</td>
      <td>파이프라인 기반 데이터 집계</td>
    </tr>
    <tr>
      <td>Change Stream</td>
      <td>실시간 데이터 변경 감지</td>
    </tr>
  </tbody>
</table>

<h2 id="mongodb-활용-사례">MongoDB 활용 사례</h2>

<table>
  <thead>
    <tr>
      <th>용도</th>
      <th>이유</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>콘텐츠 관리 (CMS)</td>
      <td>유연한 스키마, 다양한 콘텐츠 구조</td>
    </tr>
    <tr>
      <td>IoT 데이터</td>
      <td>대량 시계열 데이터, 수평 확장</td>
    </tr>
    <tr>
      <td>모바일 앱 백엔드</td>
      <td>JSON 네이티브, 빠른 개발</td>
    </tr>
    <tr>
      <td>실시간 분석</td>
      <td>Aggregation Pipeline</td>
    </tr>
    <tr>
      <td>카탈로그/상품 정보</td>
      <td>상품마다 다른 속성</td>
    </tr>
    <tr>
      <td>사용자 프로필</td>
      <td>유연한 필드 구조</td>
    </tr>
    <tr>
      <td>게임</td>
      <td>빠른 읽기/쓰기, 유연한 데이터</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="설치">설치</h2>

<h3 id="windows">Windows</h3>

<ol>
  <li><a href="https://www.mongodb.com/try/download/community" target="_blank">MongoDB 다운로드</a> 페이지에서 MSI 설치 파일 다운로드</li>
  <li><code class="language-plaintext highlighter-rouge">mongodb-windows-x86_64-x.x.x-signed.msi</code> 실행</li>
  <li>“Complete” 설치 선택</li>
  <li>“Install MongoDB as a Service” 체크</li>
  <li>MongoDB Compass (GUI) 함께 설치 선택</li>
</ol>

<h3 id="mac">Mac</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Homebrew</span>
brew tap mongodb/brew
brew <span class="nb">install </span>mongodb-community@7.0
brew services start mongodb-community@7.0
</code></pre></div></div>

<h3 id="linux-ubuntu">Linux (Ubuntu)</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># GPG 키 및 저장소 추가</span>
curl <span class="nt">-fsSL</span> https://www.mongodb.org/static/pgp/server-7.0.asc | <span class="nb">sudo </span>gpg <span class="nt">-o</span> /usr/share/keyrings/mongodb-server-7.0.gpg <span class="nt">--dearmor</span>
<span class="nb">echo</span> <span class="s2">"deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse"</span> | <span class="nb">sudo tee</span> /etc/apt/sources.list.d/mongodb-org-7.0.list

<span class="nb">sudo </span>apt update
<span class="nb">sudo </span>apt <span class="nb">install </span>mongodb-org
<span class="nb">sudo </span>systemctl start mongod
<span class="nb">sudo </span>systemctl <span class="nb">enable </span>mongod
</code></pre></div></div>

<h3 id="docker">Docker</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run <span class="nt">-d</span> <span class="se">\</span>
  <span class="nt">--name</span> mongodb <span class="se">\</span>
  <span class="nt">-p</span> 27017:27017 <span class="se">\</span>
  <span class="nt">-e</span> <span class="nv">MONGO_INITDB_ROOT_USERNAME</span><span class="o">=</span>admin <span class="se">\</span>
  <span class="nt">-e</span> <span class="nv">MONGO_INITDB_ROOT_PASSWORD</span><span class="o">=</span>MongoPass123! <span class="se">\</span>
  <span class="nt">-v</span> mongodata:/data/db <span class="se">\</span>
  mongo:7

<span class="c"># 접속</span>
docker <span class="nb">exec</span> <span class="nt">-it</span> mongodb mongosh <span class="nt">-u</span> admin <span class="nt">-p</span> MongoPass123!
</code></pre></div></div>

<h3 id="설치-확인">설치 확인</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mongosh
<span class="c"># 또는</span>
mongosh <span class="s2">"mongodb://localhost:27017"</span>

db.version<span class="o">()</span>
</code></pre></div></div>

<hr />

<h2 id="접속-방법">접속 방법</h2>

<h3 id="mongosh-mongodb-shell">mongosh (MongoDB Shell)</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 로컬 접속</span>
mongosh

<span class="c"># 인증 접속</span>
mongosh <span class="nt">-u</span> admin <span class="nt">-p</span> MongoPass123! <span class="nt">--authenticationDatabase</span> admin

<span class="c"># 원격 접속</span>
mongosh <span class="s2">"mongodb://192.168.1.100:27017"</span>

<span class="c"># Connection String (URI)</span>
mongosh <span class="s2">"mongodb://admin:MongoPass123!@localhost:27017/mydb?authSource=admin"</span>
</code></pre></div></div>

<h3 id="기본-셸-명령어">기본 셸 명령어</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">show</span> <span class="nx">dbs</span>              <span class="c1">// 데이터베이스 목록</span>
<span class="nx">use</span> <span class="nx">mydb</span>              <span class="c1">// 데이터베이스 전환 (없으면 자동 생성)</span>
<span class="nx">show</span> <span class="nx">collections</span>      <span class="c1">// 컬렉션 목록</span>
<span class="nx">db</span><span class="p">.</span><span class="nf">stats</span><span class="p">()</span>            <span class="c1">// 현재 DB 통계</span>
<span class="nx">db</span><span class="p">.</span><span class="nf">version</span><span class="p">()</span>          <span class="c1">// 버전 확인</span>
<span class="nx">exit</span>                  <span class="c1">// 종료</span>
</code></pre></div></div>

<hr />

<h2 id="gui-도구">GUI 도구</h2>

<table>
  <thead>
    <tr>
      <th>도구</th>
      <th>특징</th>
      <th>가격</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>MongoDB Compass</td>
      <td>공식 도구, 시각적 쿼리 빌더</td>
      <td>무료</td>
    </tr>
    <tr>
      <td>Studio 3T</td>
      <td>강력한 쿼리 도구, SQL→MQL 변환</td>
      <td>유료 (무료 제한판)</td>
    </tr>
    <tr>
      <td>Robo 3T (Robomongo)</td>
      <td>가볍고 빠름</td>
      <td>무료</td>
    </tr>
    <tr>
      <td>MongoDB Atlas</td>
      <td>클라우드 관리형 서비스</td>
      <td>무료 티어 있음</td>
    </tr>
    <tr>
      <td>DBeaver</td>
      <td>다중 DB 지원</td>
      <td>무료 (Community)</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="문서document-구조-예시">문서(Document) 구조 예시</h2>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// RDBMS의 한 행(Row)에 해당하는 MongoDB 문서</span>
<span class="p">{</span>
    <span class="nl">_id</span><span class="p">:</span> <span class="nc">ObjectId</span><span class="p">(</span><span class="dl">"</span><span class="s2">507f1f77bcf86cd799439011</span><span class="dl">"</span><span class="p">),</span>  <span class="c1">// 자동 생성 PK</span>
    <span class="nx">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">홍길동</span><span class="dl">"</span><span class="p">,</span>
    <span class="nx">age</span><span class="p">:</span> <span class="mi">30</span><span class="p">,</span>
    <span class="nx">email</span><span class="p">:</span> <span class="dl">"</span><span class="s2">hong@test.com</span><span class="dl">"</span><span class="p">,</span>
    <span class="nx">address</span><span class="p">:</span> <span class="p">{</span>                    <span class="c1">// 중첩 문서 (Embedded Document)</span>
        <span class="nl">city</span><span class="p">:</span> <span class="dl">"</span><span class="s2">서울</span><span class="dl">"</span><span class="p">,</span>
        <span class="nx">zipcode</span><span class="p">:</span> <span class="dl">"</span><span class="s2">06000</span><span class="dl">"</span>
    <span class="p">},</span>
    <span class="nx">hobbies</span><span class="p">:</span> <span class="p">[</span><span class="dl">"</span><span class="s2">독서</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">등산</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">코딩</span><span class="dl">"</span><span class="p">],</span>  <span class="c1">// 배열</span>
    <span class="nx">orders</span><span class="p">:</span> <span class="p">[</span>                     <span class="c1">// 배열 + 중첩 문서</span>
        <span class="p">{</span> <span class="na">product</span><span class="p">:</span> <span class="dl">"</span><span class="s2">노트북</span><span class="dl">"</span><span class="p">,</span> <span class="na">price</span><span class="p">:</span> <span class="mi">1500000</span><span class="p">,</span> <span class="na">date</span><span class="p">:</span> <span class="nc">ISODate</span><span class="p">(</span><span class="dl">"</span><span class="s2">2026-01-15</span><span class="dl">"</span><span class="p">)</span> <span class="p">},</span>
        <span class="p">{</span> <span class="na">product</span><span class="p">:</span> <span class="dl">"</span><span class="s2">마우스</span><span class="dl">"</span><span class="p">,</span> <span class="na">price</span><span class="p">:</span> <span class="mi">50000</span><span class="p">,</span> <span class="na">date</span><span class="p">:</span> <span class="nc">ISODate</span><span class="p">(</span><span class="dl">"</span><span class="s2">2026-03-20</span><span class="dl">"</span><span class="p">)</span> <span class="p">}</span>
    <span class="p">],</span>
    <span class="nx">created_at</span><span class="p">:</span> <span class="nc">ISODate</span><span class="p">(</span><span class="dl">"</span><span class="s2">2024-01-01T00:00:00Z</span><span class="dl">"</span><span class="p">),</span>
    <span class="nx">is_active</span><span class="p">:</span> <span class="kc">true</span>
<span class="p">}</span>
</code></pre></div></div>

<p><span class="nav__sub-title">관련된 글 (mongodb &gt; lecture-mongodb)</span></p>
<ul>

    

    

    

    

    

    

    

    

    

    

    

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-10-troubleshooting/">[MongoDB] 10. 자주 발생하는 Troubleshooting</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-09-performance/">[MongoDB] 09. 성능 튜닝과 모니터링</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-08-backup-restore/">[MongoDB] 08. 백업과 복구</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-07-security-user/">[MongoDB] 07. 보안과 사용자 관리</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-06-replication-sharding/">[MongoDB] 06. Replica Set과 Sharding (고가용성/확장)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-05-schema-design/">[MongoDB] 05. 스키마 설계 (Embedding vs Referencing)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-04-index/">[MongoDB] 04. 인덱스 (Index)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-03-aggregation/">[MongoDB] 03. Aggregation Pipeline (집계)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-02-crud/">[MongoDB] 02. CRUD 기본 (문서 삽입, 조회, 수정, 삭제)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-01-intro/">[MongoDB] 01. MongoDB 소개 및 설치</a></li>
             
        
      

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

</ul>]]></content><author><name>devjaedol</name></author><category term="mongodb" /><category term="mongodb" /><category term="nosql" /><category term="mongodb강좌" /><category term="초급" /><category term="lecture-mongodb" /><summary type="html"><![CDATA[MongoDB의 기본 개념, 특징, 설치 방법을 알아봅니다.]]></summary></entry><entry><title type="html">[MongoDB] 02. CRUD 기본 (문서 삽입, 조회, 수정, 삭제)</title><link href="https://kimjaehyun.co.kr/mongodb/mongodb-02-crud/" rel="alternate" type="text/html" title="[MongoDB] 02. CRUD 기본 (문서 삽입, 조회, 수정, 삭제)" /><published>2026-05-05T00:00:00+00:00</published><updated>2026-05-05T00:00:00+00:00</updated><id>https://kimjaehyun.co.kr/mongodb/mongodb-02-crud</id><content type="html" xml:base="https://kimjaehyun.co.kr/mongodb/mongodb-02-crud/"><![CDATA[<p>MongoDB에서의 문서 CRUD(Create, Read, Update, Delete) 명령어를 정리합니다.</p>

<h1 id="데이터베이스와-컬렉션">데이터베이스와 컬렉션</h1>

<h2 id="데이터베이스-관리">데이터베이스 관리</h2>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 데이터베이스 목록</span>
<span class="nx">show</span> <span class="nx">dbs</span>

<span class="c1">// 데이터베이스 전환 (없으면 첫 문서 삽입 시 자동 생성)</span>
<span class="nx">use</span> <span class="nx">mydb</span>

<span class="c1">// 현재 데이터베이스 확인</span>
<span class="nx">db</span>

<span class="c1">// 데이터베이스 삭제</span>
<span class="nx">db</span><span class="p">.</span><span class="nf">dropDatabase</span><span class="p">()</span>
</code></pre></div></div>

<h2 id="컬렉션-관리">컬렉션 관리</h2>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 컬렉션 목록</span>
<span class="nx">show</span> <span class="nx">collections</span>

<span class="c1">// 컬렉션 생성 (명시적, 보통 자동 생성)</span>
<span class="nx">db</span><span class="p">.</span><span class="nf">createCollection</span><span class="p">(</span><span class="dl">"</span><span class="s2">users</span><span class="dl">"</span><span class="p">)</span>

<span class="c1">// 옵션과 함께 생성</span>
<span class="nx">db</span><span class="p">.</span><span class="nf">createCollection</span><span class="p">(</span><span class="dl">"</span><span class="s2">logs</span><span class="dl">"</span><span class="p">,</span> <span class="p">{</span>
    <span class="na">capped</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>       <span class="c1">// 고정 크기 컬렉션</span>
    <span class="na">size</span><span class="p">:</span> <span class="mi">104857600</span><span class="p">,</span>    <span class="c1">// 100MB</span>
    <span class="na">max</span><span class="p">:</span> <span class="mi">100000</span>         <span class="c1">// 최대 문서 수</span>
<span class="p">})</span>

<span class="c1">// 컬렉션 삭제</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">drop</span><span class="p">()</span>
</code></pre></div></div>

<hr />

<h2 id="insert-문서-삽입">INSERT (문서 삽입)</h2>

<h3 id="단일-문서-삽입">단일 문서 삽입</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">insertOne</span><span class="p">({</span>
    <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">홍길동</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">age</span><span class="p">:</span> <span class="mi">30</span><span class="p">,</span>
    <span class="na">email</span><span class="p">:</span> <span class="dl">"</span><span class="s2">hong@test.com</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">개발팀</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">salary</span><span class="p">:</span> <span class="mi">5000000</span><span class="p">,</span>
    <span class="na">hire_date</span><span class="p">:</span> <span class="k">new</span> <span class="nc">Date</span><span class="p">(</span><span class="dl">"</span><span class="s2">2024-01-15</span><span class="dl">"</span><span class="p">),</span>
    <span class="na">skills</span><span class="p">:</span> <span class="p">[</span><span class="dl">"</span><span class="s2">JavaScript</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">Python</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">MongoDB</span><span class="dl">"</span><span class="p">],</span>
    <span class="na">address</span><span class="p">:</span> <span class="p">{</span> <span class="na">city</span><span class="p">:</span> <span class="dl">"</span><span class="s2">서울</span><span class="dl">"</span><span class="p">,</span> <span class="na">district</span><span class="p">:</span> <span class="dl">"</span><span class="s2">강남구</span><span class="dl">"</span> <span class="p">}</span>
<span class="p">})</span>
<span class="c1">// { acknowledged: true, insertedId: ObjectId("...") }</span>
</code></pre></div></div>

<h3 id="다중-문서-삽입">다중 문서 삽입</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">insertMany</span><span class="p">([</span>
    <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">김철수</span><span class="dl">"</span><span class="p">,</span> <span class="na">age</span><span class="p">:</span> <span class="mi">25</span><span class="p">,</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">기획팀</span><span class="dl">"</span><span class="p">,</span> <span class="na">salary</span><span class="p">:</span> <span class="mi">4500000</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">이영희</span><span class="dl">"</span><span class="p">,</span> <span class="na">age</span><span class="p">:</span> <span class="mi">28</span><span class="p">,</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">개발팀</span><span class="dl">"</span><span class="p">,</span> <span class="na">salary</span><span class="p">:</span> <span class="mi">5500000</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">박민수</span><span class="dl">"</span><span class="p">,</span> <span class="na">age</span><span class="p">:</span> <span class="mi">35</span><span class="p">,</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">디자인팀</span><span class="dl">"</span><span class="p">,</span> <span class="na">salary</span><span class="p">:</span> <span class="mi">4800000</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">최지은</span><span class="dl">"</span><span class="p">,</span> <span class="na">age</span><span class="p">:</span> <span class="mi">32</span><span class="p">,</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">개발팀</span><span class="dl">"</span><span class="p">,</span> <span class="na">salary</span><span class="p">:</span> <span class="mi">6000000</span> <span class="p">}</span>
<span class="p">])</span>
</code></pre></div></div>

<h3 id="_id-직접-지정">_id 직접 지정</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">insertOne</span><span class="p">({</span>
    <span class="na">_id</span><span class="p">:</span> <span class="dl">"</span><span class="s2">user_001</span><span class="dl">"</span><span class="p">,</span>    <span class="c1">// 직접 지정 가능 (중복 불가)</span>
    <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">관리자</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">role</span><span class="p">:</span> <span class="dl">"</span><span class="s2">admin</span><span class="dl">"</span>
<span class="p">})</span>
</code></pre></div></div>

<hr />

<h2 id="find-문서-조회">FIND (문서 조회)</h2>

<h3 id="기본-조회">기본 조회</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 전체 조회</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">()</span>

<span class="c1">// 보기 좋게 출력</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">().</span><span class="nf">pretty</span><span class="p">()</span>

<span class="c1">// 조건 조회</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">개발팀</span><span class="dl">"</span> <span class="p">})</span>

<span class="c1">// 단일 문서 조회 (첫 번째 매칭)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">findOne</span><span class="p">({</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">홍길동</span><span class="dl">"</span> <span class="p">})</span>
</code></pre></div></div>

<h3 id="비교-연산자">비교 연산자</h3>

<table>
  <thead>
    <tr>
      <th>연산자</th>
      <th>설명</th>
      <th>SQL 대응</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$eq</code></td>
      <td>같음</td>
      <td><code class="language-plaintext highlighter-rouge">=</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$ne</code></td>
      <td>같지 않음</td>
      <td><code class="language-plaintext highlighter-rouge">!=</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$gt</code></td>
      <td>초과</td>
      <td><code class="language-plaintext highlighter-rouge">&gt;</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$gte</code></td>
      <td>이상</td>
      <td><code class="language-plaintext highlighter-rouge">&gt;=</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$lt</code></td>
      <td>미만</td>
      <td><code class="language-plaintext highlighter-rouge">&lt;</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$lte</code></td>
      <td>이하</td>
      <td><code class="language-plaintext highlighter-rouge">&lt;=</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$in</code></td>
      <td>목록 포함</td>
      <td><code class="language-plaintext highlighter-rouge">IN</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$nin</code></td>
      <td>목록 미포함</td>
      <td><code class="language-plaintext highlighter-rouge">NOT IN</code></td>
    </tr>
  </tbody>
</table>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">salary</span><span class="p">:</span> <span class="p">{</span> <span class="na">$gte</span><span class="p">:</span> <span class="mi">5000000</span> <span class="p">}</span> <span class="p">})</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">age</span><span class="p">:</span> <span class="p">{</span> <span class="na">$gt</span><span class="p">:</span> <span class="mi">25</span><span class="p">,</span> <span class="na">$lt</span><span class="p">:</span> <span class="mi">35</span> <span class="p">}</span> <span class="p">})</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">dept</span><span class="p">:</span> <span class="p">{</span> <span class="na">$in</span><span class="p">:</span> <span class="p">[</span><span class="dl">"</span><span class="s2">개발팀</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">기획팀</span><span class="dl">"</span><span class="p">]</span> <span class="p">}</span> <span class="p">})</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">dept</span><span class="p">:</span> <span class="p">{</span> <span class="na">$ne</span><span class="p">:</span> <span class="dl">"</span><span class="s2">디자인팀</span><span class="dl">"</span> <span class="p">}</span> <span class="p">})</span>
</code></pre></div></div>

<h3 id="논리-연산자">논리 연산자</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// AND (기본)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">개발팀</span><span class="dl">"</span><span class="p">,</span> <span class="na">salary</span><span class="p">:</span> <span class="p">{</span> <span class="na">$gte</span><span class="p">:</span> <span class="mi">5000000</span> <span class="p">}</span> <span class="p">})</span>

<span class="c1">// $and (명시적)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">$and</span><span class="p">:</span> <span class="p">[{</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">개발팀</span><span class="dl">"</span> <span class="p">},</span> <span class="p">{</span> <span class="na">salary</span><span class="p">:</span> <span class="p">{</span> <span class="na">$gte</span><span class="p">:</span> <span class="mi">5000000</span> <span class="p">}</span> <span class="p">}]</span> <span class="p">})</span>

<span class="c1">// $or</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">$or</span><span class="p">:</span> <span class="p">[{</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">개발팀</span><span class="dl">"</span> <span class="p">},</span> <span class="p">{</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">기획팀</span><span class="dl">"</span> <span class="p">}]</span> <span class="p">})</span>

<span class="c1">// $not</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">age</span><span class="p">:</span> <span class="p">{</span> <span class="na">$not</span><span class="p">:</span> <span class="p">{</span> <span class="na">$gte</span><span class="p">:</span> <span class="mi">30</span> <span class="p">}</span> <span class="p">}</span> <span class="p">})</span>

<span class="c1">// $nor (모두 아닌)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">$nor</span><span class="p">:</span> <span class="p">[{</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">개발팀</span><span class="dl">"</span> <span class="p">},</span> <span class="p">{</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">기획팀</span><span class="dl">"</span> <span class="p">}]</span> <span class="p">})</span>
</code></pre></div></div>

<h3 id="필드타입-연산자">필드/타입 연산자</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 필드 존재 여부</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">email</span><span class="p">:</span> <span class="p">{</span> <span class="na">$exists</span><span class="p">:</span> <span class="kc">true</span> <span class="p">}</span> <span class="p">})</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">phone</span><span class="p">:</span> <span class="p">{</span> <span class="na">$exists</span><span class="p">:</span> <span class="kc">false</span> <span class="p">}</span> <span class="p">})</span>

<span class="c1">// 타입 확인</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">age</span><span class="p">:</span> <span class="p">{</span> <span class="na">$type</span><span class="p">:</span> <span class="dl">"</span><span class="s2">number</span><span class="dl">"</span> <span class="p">}</span> <span class="p">})</span>

<span class="c1">// 정규식</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">name</span><span class="p">:</span> <span class="p">{</span> <span class="na">$regex</span><span class="p">:</span> <span class="sr">/^홍/</span> <span class="p">}</span> <span class="p">})</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">email</span><span class="p">:</span> <span class="p">{</span> <span class="na">$regex</span><span class="p">:</span> <span class="sr">/test</span><span class="se">\.</span><span class="sr">com$/</span><span class="p">,</span> <span class="na">$options</span><span class="p">:</span> <span class="dl">"</span><span class="s2">i</span><span class="dl">"</span> <span class="p">}</span> <span class="p">})</span>
</code></pre></div></div>

<h3 id="배열-쿼리">배열 쿼리</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 배열에 특정 값 포함</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">skills</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Python</span><span class="dl">"</span> <span class="p">})</span>

<span class="c1">// 배열 크기</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">skills</span><span class="p">:</span> <span class="p">{</span> <span class="na">$size</span><span class="p">:</span> <span class="mi">3</span> <span class="p">}</span> <span class="p">})</span>

<span class="c1">// $all: 모든 값 포함</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">skills</span><span class="p">:</span> <span class="p">{</span> <span class="na">$all</span><span class="p">:</span> <span class="p">[</span><span class="dl">"</span><span class="s2">JavaScript</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">Python</span><span class="dl">"</span><span class="p">]</span> <span class="p">}</span> <span class="p">})</span>

<span class="c1">// $elemMatch: 배열 요소 조건</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">orders</span><span class="p">:</span> <span class="p">{</span> <span class="na">$elemMatch</span><span class="p">:</span> <span class="p">{</span> <span class="na">price</span><span class="p">:</span> <span class="p">{</span> <span class="na">$gt</span><span class="p">:</span> <span class="mi">100000</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">})</span>
</code></pre></div></div>

<h3 id="중첩-문서-쿼리">중첩 문서 쿼리</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 점 표기법 (Dot Notation)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="dl">"</span><span class="s2">address.city</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">서울</span><span class="dl">"</span> <span class="p">})</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="dl">"</span><span class="s2">orders.0.product</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">노트북</span><span class="dl">"</span> <span class="p">})</span>
</code></pre></div></div>

<h3 id="프로젝션-반환-필드-선택">프로젝션 (반환 필드 선택)</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 특정 필드만 반환 (1: 포함, 0: 제외)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({},</span> <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="na">email</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="na">_id</span><span class="p">:</span> <span class="mi">0</span> <span class="p">})</span>

<span class="c1">// 특정 필드 제외</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({},</span> <span class="p">{</span> <span class="na">password</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="na">__v</span><span class="p">:</span> <span class="mi">0</span> <span class="p">})</span>
</code></pre></div></div>

<h3 id="정렬-제한-건너뛰기">정렬, 제한, 건너뛰기</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 정렬 (1: 오름차순, -1: 내림차순)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">().</span><span class="nf">sort</span><span class="p">({</span> <span class="na">salary</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span> <span class="p">})</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">().</span><span class="nf">sort</span><span class="p">({</span> <span class="na">dept</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="na">salary</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span> <span class="p">})</span>

<span class="c1">// 제한</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">().</span><span class="nf">limit</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>

<span class="c1">// 건너뛰기 (페이징)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">().</span><span class="nf">skip</span><span class="p">(</span><span class="mi">10</span><span class="p">).</span><span class="nf">limit</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>

<span class="c1">// 개수</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">countDocuments</span><span class="p">({</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">개발팀</span><span class="dl">"</span> <span class="p">})</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">estimatedDocumentCount</span><span class="p">()</span>   <span class="c1">// 빠른 추정치</span>
</code></pre></div></div>

<hr />

<h2 id="update-문서-수정">UPDATE (문서 수정)</h2>

<h3 id="수정-연산자">수정 연산자</h3>

<table>
  <thead>
    <tr>
      <th>연산자</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$set</code></td>
      <td>필드 값 설정 (없으면 추가)</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$unset</code></td>
      <td>필드 삭제</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$inc</code></td>
      <td>숫자 증감</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$mul</code></td>
      <td>숫자 곱하기</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$rename</code></td>
      <td>필드 이름 변경</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$min</code> / <code class="language-plaintext highlighter-rouge">$max</code></td>
      <td>최소/최대값으로 갱신</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$push</code></td>
      <td>배열에 요소 추가</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$pull</code></td>
      <td>배열에서 요소 제거</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$addToSet</code></td>
      <td>배열에 중복 없이 추가</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$pop</code></td>
      <td>배열 첫/마지막 요소 제거</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$currentDate</code></td>
      <td>현재 날짜로 설정</td>
    </tr>
  </tbody>
</table>

<h3 id="단일-문서-수정">단일 문서 수정</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// $set: 필드 값 변경</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">updateOne</span><span class="p">(</span>
    <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">홍길동</span><span class="dl">"</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$set</span><span class="p">:</span> <span class="p">{</span> <span class="na">salary</span><span class="p">:</span> <span class="mi">5500000</span><span class="p">,</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">인사팀</span><span class="dl">"</span> <span class="p">}</span> <span class="p">}</span>
<span class="p">)</span>

<span class="c1">// $inc: 숫자 증감</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">updateOne</span><span class="p">(</span>
    <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">홍길동</span><span class="dl">"</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$inc</span><span class="p">:</span> <span class="p">{</span> <span class="na">salary</span><span class="p">:</span> <span class="mi">500000</span><span class="p">,</span> <span class="na">age</span><span class="p">:</span> <span class="mi">1</span> <span class="p">}</span> <span class="p">}</span>
<span class="p">)</span>

<span class="c1">// $unset: 필드 삭제</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">updateOne</span><span class="p">(</span>
    <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">홍길동</span><span class="dl">"</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$unset</span><span class="p">:</span> <span class="p">{</span> <span class="na">phone</span><span class="p">:</span> <span class="dl">""</span> <span class="p">}</span> <span class="p">}</span>
<span class="p">)</span>

<span class="c1">// $push: 배열에 추가</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">updateOne</span><span class="p">(</span>
    <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">홍길동</span><span class="dl">"</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$push</span><span class="p">:</span> <span class="p">{</span> <span class="na">skills</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Redis</span><span class="dl">"</span> <span class="p">}</span> <span class="p">}</span>
<span class="p">)</span>

<span class="c1">// $addToSet: 중복 없이 배열에 추가</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">updateOne</span><span class="p">(</span>
    <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">홍길동</span><span class="dl">"</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$addToSet</span><span class="p">:</span> <span class="p">{</span> <span class="na">skills</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Python</span><span class="dl">"</span> <span class="p">}</span> <span class="p">}</span>  <span class="c1">// 이미 있으면 무시</span>
<span class="p">)</span>

<span class="c1">// $pull: 배열에서 제거</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">updateOne</span><span class="p">(</span>
    <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">홍길동</span><span class="dl">"</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$pull</span><span class="p">:</span> <span class="p">{</span> <span class="na">skills</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Python</span><span class="dl">"</span> <span class="p">}</span> <span class="p">}</span>
<span class="p">)</span>
</code></pre></div></div>

<h3 id="다중-문서-수정">다중 문서 수정</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 조건에 맞는 모든 문서 수정</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">updateMany</span><span class="p">(</span>
    <span class="p">{</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">개발팀</span><span class="dl">"</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$inc</span><span class="p">:</span> <span class="p">{</span> <span class="na">salary</span><span class="p">:</span> <span class="mi">500000</span> <span class="p">}</span> <span class="p">}</span>
<span class="p">)</span>
</code></pre></div></div>

<h3 id="upsert-없으면-삽입-있으면-수정">Upsert (없으면 삽입, 있으면 수정)</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">updateOne</span><span class="p">(</span>
    <span class="p">{</span> <span class="na">email</span><span class="p">:</span> <span class="dl">"</span><span class="s2">new@test.com</span><span class="dl">"</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$set</span><span class="p">:</span> <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">신규유저</span><span class="dl">"</span><span class="p">,</span> <span class="na">age</span><span class="p">:</span> <span class="mi">20</span> <span class="p">}</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">upsert</span><span class="p">:</span> <span class="kc">true</span> <span class="p">}</span>
<span class="p">)</span>
</code></pre></div></div>

<h3 id="replaceone-문서-전체-교체">replaceOne (문서 전체 교체)</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">replaceOne</span><span class="p">(</span>
    <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">홍길동</span><span class="dl">"</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">홍길동</span><span class="dl">"</span><span class="p">,</span> <span class="na">age</span><span class="p">:</span> <span class="mi">31</span><span class="p">,</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">CTO</span><span class="dl">"</span><span class="p">,</span> <span class="na">salary</span><span class="p">:</span> <span class="mi">8000000</span> <span class="p">}</span>
<span class="p">)</span>
</code></pre></div></div>

<hr />

<h2 id="delete-문서-삭제">DELETE (문서 삭제)</h2>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 단일 문서 삭제</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">deleteOne</span><span class="p">({</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">홍길동</span><span class="dl">"</span> <span class="p">})</span>

<span class="c1">// 다중 문서 삭제</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">deleteMany</span><span class="p">({</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">기획팀</span><span class="dl">"</span> <span class="p">})</span>

<span class="c1">// 전체 삭제</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">deleteMany</span><span class="p">({})</span>

<span class="c1">// 컬렉션 자체 삭제 (더 빠름)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">drop</span><span class="p">()</span>
</code></pre></div></div>

<hr />

<h2 id="findoneandupdate--findoneanddelete">findOneAndUpdate / findOneAndDelete</h2>

<p>수정/삭제와 동시에 해당 문서를 반환합니다.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 수정 후 새 문서 반환</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">findOneAndUpdate</span><span class="p">(</span>
    <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">홍길동</span><span class="dl">"</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$inc</span><span class="p">:</span> <span class="p">{</span> <span class="na">salary</span><span class="p">:</span> <span class="mi">100000</span> <span class="p">}</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">returnDocument</span><span class="p">:</span> <span class="dl">"</span><span class="s2">after</span><span class="dl">"</span> <span class="p">}</span>   <span class="c1">// "before" 또는 "after"</span>
<span class="p">)</span>

<span class="c1">// 삭제하면서 삭제된 문서 반환</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">findOneAndDelete</span><span class="p">({</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">홍길동</span><span class="dl">"</span> <span class="p">})</span>
</code></pre></div></div>

<p><span class="nav__sub-title">관련된 글 (mongodb &gt; lecture-mongodb)</span></p>
<ul>

    

    

    

    

    

    

    

    

    

    

    

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-10-troubleshooting/">[MongoDB] 10. 자주 발생하는 Troubleshooting</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-09-performance/">[MongoDB] 09. 성능 튜닝과 모니터링</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-08-backup-restore/">[MongoDB] 08. 백업과 복구</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-07-security-user/">[MongoDB] 07. 보안과 사용자 관리</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-06-replication-sharding/">[MongoDB] 06. Replica Set과 Sharding (고가용성/확장)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-05-schema-design/">[MongoDB] 05. 스키마 설계 (Embedding vs Referencing)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-04-index/">[MongoDB] 04. 인덱스 (Index)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-03-aggregation/">[MongoDB] 03. Aggregation Pipeline (집계)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-02-crud/">[MongoDB] 02. CRUD 기본 (문서 삽입, 조회, 수정, 삭제)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-01-intro/">[MongoDB] 01. MongoDB 소개 및 설치</a></li>
             
        
      

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

</ul>]]></content><author><name>devjaedol</name></author><category term="mongodb" /><category term="mongodb" /><category term="nosql" /><category term="mongodb강좌" /><category term="초급" /><category term="lecture-mongodb" /><summary type="html"><![CDATA[MongoDB에서의 문서 CRUD(Create, Read, Update, Delete) 명령어를 정리합니다.]]></summary></entry><entry><title type="html">[MongoDB] 03. Aggregation Pipeline (집계)</title><link href="https://kimjaehyun.co.kr/mongodb/mongodb-03-aggregation/" rel="alternate" type="text/html" title="[MongoDB] 03. Aggregation Pipeline (집계)" /><published>2026-05-05T00:00:00+00:00</published><updated>2026-05-05T00:00:00+00:00</updated><id>https://kimjaehyun.co.kr/mongodb/mongodb-03-aggregation</id><content type="html" xml:base="https://kimjaehyun.co.kr/mongodb/mongodb-03-aggregation/"><![CDATA[<p>MongoDB의 Aggregation Pipeline을 이용한 데이터 집계와 변환을 정리합니다.</p>

<h1 id="aggregation-pipeline이란">Aggregation Pipeline이란?</h1>

<p>Aggregation Pipeline은 문서를 여러 단계(Stage)를 거쳐 변환하고 집계하는 프레임워크입니다.  <br />
RDBMS의 GROUP BY, HAVING, JOIN, 서브쿼리 등을 대체합니다.</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>컬렉션 → [Stage 1] → [Stage 2] → [Stage 3] → ... → 결과
</code></pre></div></div>

<hr />

<h2 id="주요-stage">주요 Stage</h2>

<table>
  <thead>
    <tr>
      <th>Stage</th>
      <th>설명</th>
      <th>SQL 대응</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$match</code></td>
      <td>조건 필터링</td>
      <td>WHERE</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$group</code></td>
      <td>그룹핑 및 집계</td>
      <td>GROUP BY</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$project</code></td>
      <td>필드 선택/변환</td>
      <td>SELECT</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$sort</code></td>
      <td>정렬</td>
      <td>ORDER BY</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$limit</code></td>
      <td>결과 수 제한</td>
      <td>LIMIT</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$skip</code></td>
      <td>건너뛰기</td>
      <td>OFFSET</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$unwind</code></td>
      <td>배열 펼치기</td>
      <td>-</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$lookup</code></td>
      <td>다른 컬렉션 조인</td>
      <td>JOIN</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$addFields</code></td>
      <td>필드 추가</td>
      <td>SELECT AS</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$count</code></td>
      <td>문서 수 카운트</td>
      <td>COUNT</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$out</code></td>
      <td>결과를 컬렉션에 저장</td>
      <td>INSERT INTO … SELECT</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$merge</code></td>
      <td>결과를 기존 컬렉션에 병합</td>
      <td>MERGE</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$bucket</code></td>
      <td>범위별 그룹핑</td>
      <td>-</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$facet</code></td>
      <td>다중 파이프라인 병렬 실행</td>
      <td>-</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="match-필터링">$match (필터링)</h2>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// WHERE dept = '개발팀' AND salary &gt;= 5000000</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">aggregate</span><span class="p">([</span>
    <span class="p">{</span> <span class="na">$match</span><span class="p">:</span> <span class="p">{</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">개발팀</span><span class="dl">"</span><span class="p">,</span> <span class="na">salary</span><span class="p">:</span> <span class="p">{</span> <span class="na">$gte</span><span class="p">:</span> <span class="mi">5000000</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span>
<span class="p">])</span>
</code></pre></div></div>

<h2 id="group-그룹핑">$group (그룹핑)</h2>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 부서별 인원수, 평균급여</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">aggregate</span><span class="p">([</span>
    <span class="p">{</span> <span class="na">$group</span><span class="p">:</span> <span class="p">{</span>
        <span class="na">_id</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$dept</span><span class="dl">"</span><span class="p">,</span>                    <span class="c1">// 그룹핑 기준</span>
        <span class="na">count</span><span class="p">:</span> <span class="p">{</span> <span class="na">$sum</span><span class="p">:</span> <span class="mi">1</span> <span class="p">},</span>              <span class="c1">// COUNT</span>
        <span class="na">avg_salary</span><span class="p">:</span> <span class="p">{</span> <span class="na">$avg</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$salary</span><span class="dl">"</span> <span class="p">},</span> <span class="c1">// AVG</span>
        <span class="na">max_salary</span><span class="p">:</span> <span class="p">{</span> <span class="na">$max</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$salary</span><span class="dl">"</span> <span class="p">},</span> <span class="c1">// MAX</span>
        <span class="na">min_salary</span><span class="p">:</span> <span class="p">{</span> <span class="na">$min</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$salary</span><span class="dl">"</span> <span class="p">},</span> <span class="c1">// MIN</span>
        <span class="na">total_salary</span><span class="p">:</span> <span class="p">{</span> <span class="na">$sum</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$salary</span><span class="dl">"</span> <span class="p">}</span> <span class="c1">// SUM</span>
    <span class="p">}}</span>
<span class="p">])</span>
</code></pre></div></div>

<h3 id="집계-연산자">집계 연산자</h3>

<table>
  <thead>
    <tr>
      <th>연산자</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$sum</code></td>
      <td>합계 (1이면 카운트)</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$avg</code></td>
      <td>평균</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$min</code> / <code class="language-plaintext highlighter-rouge">$max</code></td>
      <td>최소/최대</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$first</code> / <code class="language-plaintext highlighter-rouge">$last</code></td>
      <td>첫 번째/마지막 값</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$push</code></td>
      <td>배열로 수집</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$addToSet</code></td>
      <td>중복 없이 배열로 수집</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">$count</code></td>
      <td>문서 수</td>
    </tr>
  </tbody>
</table>

<h2 id="project-필드-선택변환">$project (필드 선택/변환)</h2>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">aggregate</span><span class="p">([</span>
    <span class="p">{</span> <span class="na">$project</span><span class="p">:</span> <span class="p">{</span>
        <span class="na">_id</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
        <span class="na">name</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
        <span class="na">dept</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
        <span class="na">annual_salary</span><span class="p">:</span> <span class="p">{</span> <span class="na">$multiply</span><span class="p">:</span> <span class="p">[</span><span class="dl">"</span><span class="s2">$salary</span><span class="dl">"</span><span class="p">,</span> <span class="mi">12</span><span class="p">]</span> <span class="p">},</span>
        <span class="na">name_dept</span><span class="p">:</span> <span class="p">{</span> <span class="na">$concat</span><span class="p">:</span> <span class="p">[</span><span class="dl">"</span><span class="s2">$name</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2"> (</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">$dept</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">)</span><span class="dl">"</span><span class="p">]</span> <span class="p">}</span>
    <span class="p">}}</span>
<span class="p">])</span>
</code></pre></div></div>

<h2 id="sort--limit--skip">$sort / $limit / $skip</h2>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 급여 높은 순 상위 5명</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">aggregate</span><span class="p">([</span>
    <span class="p">{</span> <span class="na">$sort</span><span class="p">:</span> <span class="p">{</span> <span class="na">salary</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span> <span class="p">}</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$limit</span><span class="p">:</span> <span class="mi">5</span> <span class="p">}</span>
<span class="p">])</span>

<span class="c1">// 페이징 (2페이지, 페이지당 10건)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">aggregate</span><span class="p">([</span>
    <span class="p">{</span> <span class="na">$sort</span><span class="p">:</span> <span class="p">{</span> <span class="na">_id</span><span class="p">:</span> <span class="mi">1</span> <span class="p">}</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$skip</span><span class="p">:</span> <span class="mi">10</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$limit</span><span class="p">:</span> <span class="mi">10</span> <span class="p">}</span>
<span class="p">])</span>
</code></pre></div></div>

<hr />

<h2 id="unwind-배열-펼치기">$unwind (배열 펼치기)</h2>

<p>배열 필드를 개별 문서로 분리합니다.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 원본: { name: "홍길동", skills: ["JS", "Python", "MongoDB"] }</span>
<span class="c1">// 결과: 3개 문서로 분리</span>

<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">aggregate</span><span class="p">([</span>
    <span class="p">{</span> <span class="na">$unwind</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$skills</span><span class="dl">"</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$group</span><span class="p">:</span> <span class="p">{</span>
        <span class="na">_id</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$skills</span><span class="dl">"</span><span class="p">,</span>
        <span class="na">count</span><span class="p">:</span> <span class="p">{</span> <span class="na">$sum</span><span class="p">:</span> <span class="mi">1</span> <span class="p">}</span>
    <span class="p">}},</span>
    <span class="p">{</span> <span class="na">$sort</span><span class="p">:</span> <span class="p">{</span> <span class="na">count</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span> <span class="p">}</span> <span class="p">}</span>
<span class="p">])</span>
<span class="c1">// 스킬별 보유 인원 수</span>
</code></pre></div></div>

<hr />

<h2 id="lookup-join">$lookup (JOIN)</h2>

<p>다른 컬렉션과 조인합니다.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// users 컬렉션의 dept_id로 departments 컬렉션 조인</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">aggregate</span><span class="p">([</span>
    <span class="p">{</span> <span class="na">$lookup</span><span class="p">:</span> <span class="p">{</span>
        <span class="na">from</span><span class="p">:</span> <span class="dl">"</span><span class="s2">departments</span><span class="dl">"</span><span class="p">,</span>        <span class="c1">// 조인할 컬렉션</span>
        <span class="na">localField</span><span class="p">:</span> <span class="dl">"</span><span class="s2">dept_id</span><span class="dl">"</span><span class="p">,</span>      <span class="c1">// 현재 컬렉션 필드</span>
        <span class="na">foreignField</span><span class="p">:</span> <span class="dl">"</span><span class="s2">_id</span><span class="dl">"</span><span class="p">,</span>        <span class="c1">// 대상 컬렉션 필드</span>
        <span class="na">as</span><span class="p">:</span> <span class="dl">"</span><span class="s2">dept_info</span><span class="dl">"</span>             <span class="c1">// 결과 배열 필드명</span>
    <span class="p">}},</span>
    <span class="p">{</span> <span class="na">$unwind</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$dept_info</span><span class="dl">"</span> <span class="p">},</span>      <span class="c1">// 배열을 단일 문서로</span>
    <span class="p">{</span> <span class="na">$project</span><span class="p">:</span> <span class="p">{</span>
        <span class="na">name</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
        <span class="na">salary</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
        <span class="na">dept_name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$dept_info.name</span><span class="dl">"</span>
    <span class="p">}}</span>
<span class="p">])</span>
</code></pre></div></div>

<h3 id="pipeline-lookup-복잡한-조인-mongodb-36">Pipeline $lookup (복잡한 조인, MongoDB 3.6+)</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">db</span><span class="p">.</span><span class="nx">orders</span><span class="p">.</span><span class="nf">aggregate</span><span class="p">([</span>
    <span class="p">{</span> <span class="na">$lookup</span><span class="p">:</span> <span class="p">{</span>
        <span class="na">from</span><span class="p">:</span> <span class="dl">"</span><span class="s2">products</span><span class="dl">"</span><span class="p">,</span>
        <span class="na">let</span><span class="p">:</span> <span class="p">{</span> <span class="na">product_id</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$product_id</span><span class="dl">"</span> <span class="p">},</span>
        <span class="na">pipeline</span><span class="p">:</span> <span class="p">[</span>
            <span class="p">{</span> <span class="na">$match</span><span class="p">:</span> <span class="p">{</span> <span class="na">$expr</span><span class="p">:</span> <span class="p">{</span> <span class="na">$eq</span><span class="p">:</span> <span class="p">[</span><span class="dl">"</span><span class="s2">$_id</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">$$product_id</span><span class="dl">"</span><span class="p">]</span> <span class="p">}</span> <span class="p">}</span> <span class="p">},</span>
            <span class="p">{</span> <span class="na">$project</span><span class="p">:</span> <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="na">price</span><span class="p">:</span> <span class="mi">1</span> <span class="p">}</span> <span class="p">}</span>
        <span class="p">],</span>
        <span class="na">as</span><span class="p">:</span> <span class="dl">"</span><span class="s2">product</span><span class="dl">"</span>
    <span class="p">}}</span>
<span class="p">])</span>
</code></pre></div></div>

<hr />

<h2 id="addfields--set">$addFields / $set</h2>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 기존 필드 유지하면서 새 필드 추가</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">aggregate</span><span class="p">([</span>
    <span class="p">{</span> <span class="na">$addFields</span><span class="p">:</span> <span class="p">{</span>
        <span class="na">annual_salary</span><span class="p">:</span> <span class="p">{</span> <span class="na">$multiply</span><span class="p">:</span> <span class="p">[</span><span class="dl">"</span><span class="s2">$salary</span><span class="dl">"</span><span class="p">,</span> <span class="mi">12</span><span class="p">]</span> <span class="p">},</span>
        <span class="na">is_senior</span><span class="p">:</span> <span class="p">{</span> <span class="na">$gte</span><span class="p">:</span> <span class="p">[</span><span class="dl">"</span><span class="s2">$age</span><span class="dl">"</span><span class="p">,</span> <span class="mi">30</span><span class="p">]</span> <span class="p">}</span>
    <span class="p">}}</span>
<span class="p">])</span>
</code></pre></div></div>

<hr />

<h2 id="bucket-범위별-그룹핑">$bucket (범위별 그룹핑)</h2>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 급여 구간별 인원 수</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">aggregate</span><span class="p">([</span>
    <span class="p">{</span> <span class="na">$bucket</span><span class="p">:</span> <span class="p">{</span>
        <span class="na">groupBy</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$salary</span><span class="dl">"</span><span class="p">,</span>
        <span class="na">boundaries</span><span class="p">:</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3000000</span><span class="p">,</span> <span class="mi">5000000</span><span class="p">,</span> <span class="mi">7000000</span><span class="p">,</span> <span class="mi">10000000</span><span class="p">],</span>
        <span class="na">default</span><span class="p">:</span> <span class="dl">"</span><span class="s2">기타</span><span class="dl">"</span><span class="p">,</span>
        <span class="na">output</span><span class="p">:</span> <span class="p">{</span>
            <span class="na">count</span><span class="p">:</span> <span class="p">{</span> <span class="na">$sum</span><span class="p">:</span> <span class="mi">1</span> <span class="p">},</span>
            <span class="na">names</span><span class="p">:</span> <span class="p">{</span> <span class="na">$push</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$name</span><span class="dl">"</span> <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}}</span>
<span class="p">])</span>
</code></pre></div></div>

<hr />

<h2 id="facet-다중-파이프라인">$facet (다중 파이프라인)</h2>

<p>하나의 입력으로 여러 파이프라인을 동시에 실행합니다.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">aggregate</span><span class="p">([</span>
    <span class="p">{</span> <span class="na">$facet</span><span class="p">:</span> <span class="p">{</span>
        <span class="dl">"</span><span class="s2">부서별통계</span><span class="dl">"</span><span class="p">:</span> <span class="p">[</span>
            <span class="p">{</span> <span class="na">$group</span><span class="p">:</span> <span class="p">{</span> <span class="na">_id</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$dept</span><span class="dl">"</span><span class="p">,</span> <span class="na">count</span><span class="p">:</span> <span class="p">{</span> <span class="na">$sum</span><span class="p">:</span> <span class="mi">1</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span>
        <span class="p">],</span>
        <span class="dl">"</span><span class="s2">급여상위3</span><span class="dl">"</span><span class="p">:</span> <span class="p">[</span>
            <span class="p">{</span> <span class="na">$sort</span><span class="p">:</span> <span class="p">{</span> <span class="na">salary</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span> <span class="p">}</span> <span class="p">},</span>
            <span class="p">{</span> <span class="na">$limit</span><span class="p">:</span> <span class="mi">3</span> <span class="p">},</span>
            <span class="p">{</span> <span class="na">$project</span><span class="p">:</span> <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="na">salary</span><span class="p">:</span> <span class="mi">1</span> <span class="p">}</span> <span class="p">}</span>
        <span class="p">],</span>
        <span class="dl">"</span><span class="s2">전체통계</span><span class="dl">"</span><span class="p">:</span> <span class="p">[</span>
            <span class="p">{</span> <span class="na">$group</span><span class="p">:</span> <span class="p">{</span> <span class="na">_id</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span> <span class="na">total</span><span class="p">:</span> <span class="p">{</span> <span class="na">$sum</span><span class="p">:</span> <span class="mi">1</span> <span class="p">},</span> <span class="na">avg_salary</span><span class="p">:</span> <span class="p">{</span> <span class="na">$avg</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$salary</span><span class="dl">"</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span>
        <span class="p">]</span>
    <span class="p">}}</span>
<span class="p">])</span>
</code></pre></div></div>

<hr />

<h2 id="실전-예시-sql--aggregation-변환">실전 예시: SQL → Aggregation 변환</h2>

<h3 id="sql">SQL</h3>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">dept</span><span class="p">,</span> <span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> <span class="k">as</span> <span class="k">count</span><span class="p">,</span> <span class="k">AVG</span><span class="p">(</span><span class="n">salary</span><span class="p">)</span> <span class="k">as</span> <span class="n">avg_sal</span>
<span class="k">FROM</span> <span class="n">users</span>
<span class="k">WHERE</span> <span class="n">age</span> <span class="o">&gt;=</span> <span class="mi">25</span>
<span class="k">GROUP</span> <span class="k">BY</span> <span class="n">dept</span>
<span class="k">HAVING</span> <span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<span class="k">ORDER</span> <span class="k">BY</span> <span class="n">avg_sal</span> <span class="k">DESC</span><span class="p">;</span>
</code></pre></div></div>

<h3 id="mongodb-aggregation">MongoDB Aggregation</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">aggregate</span><span class="p">([</span>
    <span class="p">{</span> <span class="na">$match</span><span class="p">:</span> <span class="p">{</span> <span class="na">age</span><span class="p">:</span> <span class="p">{</span> <span class="na">$gte</span><span class="p">:</span> <span class="mi">25</span> <span class="p">}</span> <span class="p">}</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$group</span><span class="p">:</span> <span class="p">{</span>
        <span class="na">_id</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$dept</span><span class="dl">"</span><span class="p">,</span>
        <span class="na">count</span><span class="p">:</span> <span class="p">{</span> <span class="na">$sum</span><span class="p">:</span> <span class="mi">1</span> <span class="p">},</span>
        <span class="na">avg_sal</span><span class="p">:</span> <span class="p">{</span> <span class="na">$avg</span><span class="p">:</span> <span class="dl">"</span><span class="s2">$salary</span><span class="dl">"</span> <span class="p">}</span>
    <span class="p">}},</span>
    <span class="p">{</span> <span class="na">$match</span><span class="p">:</span> <span class="p">{</span> <span class="na">count</span><span class="p">:</span> <span class="p">{</span> <span class="na">$gte</span><span class="p">:</span> <span class="mi">2</span> <span class="p">}</span> <span class="p">}</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">$sort</span><span class="p">:</span> <span class="p">{</span> <span class="na">avg_sal</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span> <span class="p">}</span> <span class="p">}</span>
<span class="p">])</span>
</code></pre></div></div>

<p><span class="nav__sub-title">관련된 글 (mongodb &gt; lecture-mongodb)</span></p>
<ul>

    

    

    

    

    

    

    

    

    

    

    

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-10-troubleshooting/">[MongoDB] 10. 자주 발생하는 Troubleshooting</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-09-performance/">[MongoDB] 09. 성능 튜닝과 모니터링</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-08-backup-restore/">[MongoDB] 08. 백업과 복구</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-07-security-user/">[MongoDB] 07. 보안과 사용자 관리</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-06-replication-sharding/">[MongoDB] 06. Replica Set과 Sharding (고가용성/확장)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-05-schema-design/">[MongoDB] 05. 스키마 설계 (Embedding vs Referencing)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-04-index/">[MongoDB] 04. 인덱스 (Index)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-03-aggregation/">[MongoDB] 03. Aggregation Pipeline (집계)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-02-crud/">[MongoDB] 02. CRUD 기본 (문서 삽입, 조회, 수정, 삭제)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-01-intro/">[MongoDB] 01. MongoDB 소개 및 설치</a></li>
             
        
      

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

</ul>]]></content><author><name>devjaedol</name></author><category term="mongodb" /><category term="mongodb" /><category term="nosql" /><category term="mongodb강좌" /><category term="중급" /><category term="lecture-mongodb" /><summary type="html"><![CDATA[MongoDB의 Aggregation Pipeline을 이용한 데이터 집계와 변환을 정리합니다.]]></summary></entry><entry><title type="html">[MongoDB] 04. 인덱스 (Index)</title><link href="https://kimjaehyun.co.kr/mongodb/mongodb-04-index/" rel="alternate" type="text/html" title="[MongoDB] 04. 인덱스 (Index)" /><published>2026-05-05T00:00:00+00:00</published><updated>2026-05-05T00:00:00+00:00</updated><id>https://kimjaehyun.co.kr/mongodb/mongodb-04-index</id><content type="html" xml:base="https://kimjaehyun.co.kr/mongodb/mongodb-04-index/"><![CDATA[<p>MongoDB 인덱스의 종류, 생성/관리 방법, 실행 계획 분석을 정리합니다.</p>

<h1 id="인덱스-종류">인덱스 종류</h1>

<table>
  <thead>
    <tr>
      <th>종류</th>
      <th>설명</th>
      <th>용도</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Single Field</td>
      <td>단일 필드 인덱스</td>
      <td>기본 검색</td>
    </tr>
    <tr>
      <td>Compound</td>
      <td>복합 인덱스 (다중 필드)</td>
      <td>다중 조건 검색</td>
    </tr>
    <tr>
      <td>Multikey</td>
      <td>배열 필드 인덱스</td>
      <td>배열 요소 검색</td>
    </tr>
    <tr>
      <td>Text</td>
      <td>전문 검색 인덱스</td>
      <td>텍스트 검색</td>
    </tr>
    <tr>
      <td>2dsphere</td>
      <td>지리공간 인덱스</td>
      <td>위치 기반 검색</td>
    </tr>
    <tr>
      <td>Hashed</td>
      <td>해시 인덱스</td>
      <td>샤딩 키</td>
    </tr>
    <tr>
      <td>TTL</td>
      <td>자동 만료 인덱스</td>
      <td>시간 기반 자동 삭제</td>
    </tr>
    <tr>
      <td>Unique</td>
      <td>유니크 인덱스</td>
      <td>중복 방지</td>
    </tr>
    <tr>
      <td>Partial</td>
      <td>부분 인덱스 (조건부)</td>
      <td>특정 조건 문서만</td>
    </tr>
    <tr>
      <td>Wildcard</td>
      <td>와일드카드 인덱스</td>
      <td>동적 필드 검색</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="인덱스-생성-및-관리">인덱스 생성 및 관리</h2>

<h3 id="생성">생성</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 단일 필드 (1: 오름차순, -1: 내림차순)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">createIndex</span><span class="p">({</span> <span class="na">email</span><span class="p">:</span> <span class="mi">1</span> <span class="p">})</span>

<span class="c1">// 유니크 인덱스</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">createIndex</span><span class="p">({</span> <span class="na">email</span><span class="p">:</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="na">unique</span><span class="p">:</span> <span class="kc">true</span> <span class="p">})</span>

<span class="c1">// 복합 인덱스</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">createIndex</span><span class="p">({</span> <span class="na">dept</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="na">salary</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span> <span class="p">})</span>

<span class="c1">// 배열 필드 (Multikey, 자동 감지)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">createIndex</span><span class="p">({</span> <span class="na">skills</span><span class="p">:</span> <span class="mi">1</span> <span class="p">})</span>

<span class="c1">// TTL 인덱스 (60초 후 자동 삭제)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">sessions</span><span class="p">.</span><span class="nf">createIndex</span><span class="p">({</span> <span class="na">created_at</span><span class="p">:</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="na">expireAfterSeconds</span><span class="p">:</span> <span class="mi">60</span> <span class="p">})</span>

<span class="c1">// 부분 인덱스 (조건 만족하는 문서만)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">createIndex</span><span class="p">(</span>
    <span class="p">{</span> <span class="na">email</span><span class="p">:</span> <span class="mi">1</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">partialFilterExpression</span><span class="p">:</span> <span class="p">{</span> <span class="na">is_active</span><span class="p">:</span> <span class="kc">true</span> <span class="p">}</span> <span class="p">}</span>
<span class="p">)</span>

<span class="c1">// 텍스트 인덱스</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">articles</span><span class="p">.</span><span class="nf">createIndex</span><span class="p">({</span> <span class="na">title</span><span class="p">:</span> <span class="dl">"</span><span class="s2">text</span><span class="dl">"</span><span class="p">,</span> <span class="na">content</span><span class="p">:</span> <span class="dl">"</span><span class="s2">text</span><span class="dl">"</span> <span class="p">})</span>

<span class="c1">// 지리공간 인덱스</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">stores</span><span class="p">.</span><span class="nf">createIndex</span><span class="p">({</span> <span class="na">location</span><span class="p">:</span> <span class="dl">"</span><span class="s2">2dsphere</span><span class="dl">"</span> <span class="p">})</span>

<span class="c1">// 와일드카드 인덱스 (동적 필드)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">products</span><span class="p">.</span><span class="nf">createIndex</span><span class="p">({</span> <span class="dl">"</span><span class="s2">attributes.$**</span><span class="dl">"</span><span class="p">:</span> <span class="mi">1</span> <span class="p">})</span>

<span class="c1">// 백그라운드 생성 (MongoDB 4.2+ 기본)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">createIndex</span><span class="p">({</span> <span class="na">name</span><span class="p">:</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">idx_name</span><span class="dl">"</span> <span class="p">})</span>
</code></pre></div></div>

<h3 id="조회">조회</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 인덱스 목록</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">getIndexes</span><span class="p">()</span>

<span class="c1">// 인덱스 크기</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">stats</span><span class="p">().</span><span class="nx">indexSizes</span>

<span class="c1">// 인덱스 사용 통계</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">aggregate</span><span class="p">([{</span> <span class="na">$indexStats</span><span class="p">:</span> <span class="p">{}</span> <span class="p">}])</span>
</code></pre></div></div>

<h3 id="삭제">삭제</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 이름으로 삭제</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">dropIndex</span><span class="p">(</span><span class="dl">"</span><span class="s2">idx_name</span><span class="dl">"</span><span class="p">)</span>

<span class="c1">// 정의로 삭제</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">dropIndex</span><span class="p">({</span> <span class="na">email</span><span class="p">:</span> <span class="mi">1</span> <span class="p">})</span>

<span class="c1">// _id 제외 모든 인덱스 삭제</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">dropIndexes</span><span class="p">()</span>
</code></pre></div></div>

<hr />

<h2 id="실행-계획-explain">실행 계획 (explain)</h2>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 실행 계획 확인</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">dept</span><span class="p">:</span> <span class="dl">"</span><span class="s2">개발팀</span><span class="dl">"</span> <span class="p">}).</span><span class="nf">explain</span><span class="p">(</span><span class="dl">"</span><span class="s2">executionStats</span><span class="dl">"</span><span class="p">)</span>
</code></pre></div></div>

<h3 id="주요-확인-항목">주요 확인 항목</h3>

<table>
  <thead>
    <tr>
      <th>항목</th>
      <th>설명</th>
      <th>좋은 값</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>stage</td>
      <td>실행 단계</td>
      <td>IXSCAN (인덱스 사용)</td>
    </tr>
    <tr>
      <td>nReturned</td>
      <td>반환된 문서 수</td>
      <td>적을수록 좋음</td>
    </tr>
    <tr>
      <td>totalDocsExamined</td>
      <td>검사한 문서 수</td>
      <td>nReturned에 가까울수록 좋음</td>
    </tr>
    <tr>
      <td>totalKeysExamined</td>
      <td>검사한 인덱스 키 수</td>
      <td>nReturned에 가까울수록 좋음</td>
    </tr>
    <tr>
      <td>executionTimeMillis</td>
      <td>실행 시간 (ms)</td>
      <td>작을수록 좋음</td>
    </tr>
  </tbody>
</table>

<h3 id="stage-종류">Stage 종류</h3>

<table>
  <thead>
    <tr>
      <th>Stage</th>
      <th>설명</th>
      <th>성능</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>COLLSCAN</td>
      <td>컬렉션 전체 스캔</td>
      <td>나쁨</td>
    </tr>
    <tr>
      <td>IXSCAN</td>
      <td>인덱스 스캔</td>
      <td>좋음</td>
    </tr>
    <tr>
      <td>FETCH</td>
      <td>인덱스 후 문서 접근</td>
      <td>보통</td>
    </tr>
    <tr>
      <td>SORT</td>
      <td>메모리 정렬</td>
      <td>인덱스 정렬 권장</td>
    </tr>
    <tr>
      <td>PROJECTION_COVERED</td>
      <td>인덱스만으로 처리 (커버링)</td>
      <td>최고</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="복합-인덱스-설계-esr-규칙">복합 인덱스 설계 (ESR 규칙)</h2>

<p>복합 인덱스의 필드 순서는 성능에 큰 영향을 미칩니다.</p>

<h3 id="esr-규칙-equality--sort--range">ESR 규칙 (Equality → Sort → Range)</h3>

<table>
  <thead>
    <tr>
      <th>순서</th>
      <th>유형</th>
      <th>예시</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Equality (등치)</td>
      <td><code class="language-plaintext highlighter-rouge">dept = "개발팀"</code></td>
    </tr>
    <tr>
      <td>2</td>
      <td>Sort (정렬)</td>
      <td><code class="language-plaintext highlighter-rouge">ORDER BY salary DESC</code></td>
    </tr>
    <tr>
      <td>3</td>
      <td>Range (범위)</td>
      <td><code class="language-plaintext highlighter-rouge">age &gt;= 25</code></td>
    </tr>
  </tbody>
</table>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 쿼리: dept = "개발팀" AND age &gt;= 25 ORDER BY salary DESC</span>
<span class="c1">// 최적 인덱스: { dept: 1, salary: -1, age: 1 }</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nf">createIndex</span><span class="p">({</span> <span class="na">dept</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="na">salary</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="na">age</span><span class="p">:</span> <span class="mi">1</span> <span class="p">})</span>
</code></pre></div></div>

<hr />

<h2 id="ttl-인덱스-자동-만료">TTL 인덱스 (자동 만료)</h2>

<p>지정된 시간이 지나면 문서를 자동으로 삭제합니다. 세션, 로그, 임시 데이터에 유용합니다.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 30분 후 자동 삭제</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">sessions</span><span class="p">.</span><span class="nf">createIndex</span><span class="p">({</span> <span class="na">created_at</span><span class="p">:</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="na">expireAfterSeconds</span><span class="p">:</span> <span class="mi">1800</span> <span class="p">})</span>

<span class="c1">// 특정 시점에 삭제 (expireAt 필드 값 기준)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nf">createIndex</span><span class="p">({</span> <span class="na">expireAt</span><span class="p">:</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="na">expireAfterSeconds</span><span class="p">:</span> <span class="mi">0</span> <span class="p">})</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nf">insertOne</span><span class="p">({</span>
    <span class="na">event</span><span class="p">:</span> <span class="dl">"</span><span class="s2">promotion</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">expireAt</span><span class="p">:</span> <span class="k">new</span> <span class="nc">Date</span><span class="p">(</span><span class="dl">"</span><span class="s2">2026-12-31T23:59:59Z</span><span class="dl">"</span><span class="p">)</span>  <span class="c1">// 이 시점에 삭제</span>
<span class="p">})</span>
</code></pre></div></div>

<hr />

<h2 id="텍스트-인덱스와-검색">텍스트 인덱스와 검색</h2>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 텍스트 인덱스 생성</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">articles</span><span class="p">.</span><span class="nf">createIndex</span><span class="p">({</span> <span class="na">title</span><span class="p">:</span> <span class="dl">"</span><span class="s2">text</span><span class="dl">"</span><span class="p">,</span> <span class="na">content</span><span class="p">:</span> <span class="dl">"</span><span class="s2">text</span><span class="dl">"</span> <span class="p">})</span>

<span class="c1">// 텍스트 검색</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">articles</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">$text</span><span class="p">:</span> <span class="p">{</span> <span class="na">$search</span><span class="p">:</span> <span class="dl">"</span><span class="s2">MongoDB 튜토리얼</span><span class="dl">"</span> <span class="p">}</span> <span class="p">})</span>

<span class="c1">// 관련도 점수와 함께</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">articles</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span>
    <span class="p">{</span> <span class="na">$text</span><span class="p">:</span> <span class="p">{</span> <span class="na">$search</span><span class="p">:</span> <span class="dl">"</span><span class="s2">MongoDB</span><span class="dl">"</span> <span class="p">}</span> <span class="p">},</span>
    <span class="p">{</span> <span class="na">score</span><span class="p">:</span> <span class="p">{</span> <span class="na">$meta</span><span class="p">:</span> <span class="dl">"</span><span class="s2">textScore</span><span class="dl">"</span> <span class="p">}</span> <span class="p">}</span>
<span class="p">).</span><span class="nf">sort</span><span class="p">({</span> <span class="na">score</span><span class="p">:</span> <span class="p">{</span> <span class="na">$meta</span><span class="p">:</span> <span class="dl">"</span><span class="s2">textScore</span><span class="dl">"</span> <span class="p">}</span> <span class="p">})</span>

<span class="c1">// 구문 검색 (정확한 문구)</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">articles</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">$text</span><span class="p">:</span> <span class="p">{</span> <span class="na">$search</span><span class="p">:</span> <span class="dl">'</span><span class="s1">"MongoDB 설치"</span><span class="dl">'</span> <span class="p">}</span> <span class="p">})</span>

<span class="c1">// 제외 검색</span>
<span class="nx">db</span><span class="p">.</span><span class="nx">articles</span><span class="p">.</span><span class="nf">find</span><span class="p">({</span> <span class="na">$text</span><span class="p">:</span> <span class="p">{</span> <span class="na">$search</span><span class="p">:</span> <span class="dl">"</span><span class="s2">MongoDB -설치</span><span class="dl">"</span> <span class="p">}</span> <span class="p">})</span>
</code></pre></div></div>

<hr />

<h2 id="인덱스-설계-가이드라인">인덱스 설계 가이드라인</h2>

<table>
  <thead>
    <tr>
      <th>원칙</th>
      <th>설명</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>쿼리 패턴 분석</td>
      <td>자주 사용하는 쿼리 기준으로 설계</td>
    </tr>
    <tr>
      <td>ESR 규칙 준수</td>
      <td>Equality → Sort → Range 순서</td>
    </tr>
    <tr>
      <td>커버링 인덱스 활용</td>
      <td>쿼리에 필요한 필드를 모두 인덱스에 포함</td>
    </tr>
    <tr>
      <td>과도한 인덱스 지양</td>
      <td>쓰기 성능 저하, 메모리 사용 증가</td>
    </tr>
    <tr>
      <td>부분 인덱스 활용</td>
      <td>조건에 맞는 문서만 인덱싱</td>
    </tr>
    <tr>
      <td>인덱스 사용 모니터링</td>
      <td><code class="language-plaintext highlighter-rouge">$indexStats</code>로 미사용 인덱스 확인</td>
    </tr>
  </tbody>
</table>

<p><span class="nav__sub-title">관련된 글 (mongodb &gt; lecture-mongodb)</span></p>
<ul>

    

    

    

    

    

    

    

    

    

    

    

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-10-troubleshooting/">[MongoDB] 10. 자주 발생하는 Troubleshooting</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-09-performance/">[MongoDB] 09. 성능 튜닝과 모니터링</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-08-backup-restore/">[MongoDB] 08. 백업과 복구</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-07-security-user/">[MongoDB] 07. 보안과 사용자 관리</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-06-replication-sharding/">[MongoDB] 06. Replica Set과 Sharding (고가용성/확장)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-05-schema-design/">[MongoDB] 05. 스키마 설계 (Embedding vs Referencing)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-04-index/">[MongoDB] 04. 인덱스 (Index)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-03-aggregation/">[MongoDB] 03. Aggregation Pipeline (집계)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-02-crud/">[MongoDB] 02. CRUD 기본 (문서 삽입, 조회, 수정, 삭제)</a></li>
             
        
      

    
        
             
        
             
        
             
        
             
        
              
                <li><a href="/mongodb/mongodb-01-intro/">[MongoDB] 01. MongoDB 소개 및 설치</a></li>
             
        
      

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

    

</ul>]]></content><author><name>devjaedol</name></author><category term="mongodb" /><category term="mongodb" /><category term="nosql" /><category term="mongodb강좌" /><category term="중급" /><category term="lecture-mongodb" /><summary type="html"><![CDATA[MongoDB 인덱스의 종류, 생성/관리 방법, 실행 계획 분석을 정리합니다.]]></summary></entry></feed>