1. 공간 정보 인덱스
- 몽고DB는 2dsphere와 2d라는 공간 정보 인덱스를 가짐
- 2dsphere 인덱스는 WGS84 좌표계를 기반으로 지표면을 모델링하는 구면 기하학으로 작동
- 2dsphere 인덱스를 사용하면 지구의 형태를 고려하므로 2d 인덱스를 사용할 때보다 더 정확한 거리 계산을 할 수 있음
- 대신 2차원 평면의 점에는 2d 인덱스를 사용하는 것을 권장
- 2dsphere를 사용하면 GeoJSON 형식으로 점, 선, 다각형의 기하 구조를 지정할 수 있으며 점은 경도 좌표와 위도 좌표를 요소로 갖는 배열 [경도, 위도]로 표현됨
- createIndex와 함께 `2dsphere`를 사용해 공간 정보 인덱스를 생성할 수 있음
- 2dsphere 인덱스를 생성하려면 인덱싱할 도형이 포함된 필드를 지정하는 도큐먼트를 createIndex에 전달하고 "2dsphere"를 값으로 지정
db.openStreetMap.createIndex({"loc": "2dsphere"})
1.1 공간 정보 쿼리 유형
- 공간 정보 쿼리는 세 가지 유형 존재
- 교차 (Intersection)
- 포함 (within)
- 근접 (nearness)
- 찾을 항목을 {"$geometry": geoJsonDesc}와 같은 GeoJSON 객체로 지정
- "$geoIntersects" 연산자를 사용해 쿼리 위치와 교차하는 도큐먼트를 찾을 수 있음
- "$geoWithin"을 사용해 특정 지역에 완전히 포함된 항목을 쿼리 가능
- 마지막으로 "$near"를 사용해 주변 위치에 쿼리 할 수 있음, "$near"는 정렬을 포함하는 유일한 공간 정보 연산자로 결과는 항상 거리가 가장 가까운 곳부터 가장 먼 곳 순으로 반환됨
1.2 공간 정보 인덱스 사용
- 몽고DB의 공간 정보 인덱스를 사용하면 특정 지역과 관련된 모양과 점이 포함된 컬렉션에서 공간 쿼리를 효율적으로 실행할 수 있음
실생활 예시를 통해 "$geoWithin", "$geoIntersects", 그리고 "$geoNear"와 함께 사용하는 방법을 알아보겠습니다.
사용자가 뉴욕에서 레스토랑을 찾도록 돕는 모바일 애플리케이션을 설계한다고 가정했을 때 애플리케이션은 다음을 충족해야 합니다.
- 사용자가 현재 위치한 지역을 찾는다
- 해당 지역 내 레스토랑 수를 보여준다
- 지정된 거리 내에 있는 레스토랑을 찾는다
- 구면 기하학 데이터를 쿼리 하는 데 2dsphere 인덱스를 사용
가. 쿼리에서의 2D vs 구면 기하학
- 공간 정보 쿼리는 쿼리와 사용 중인 인덱스 유형에 따라 구면 또는 2D 구조를 사용
- 2d 인덱스는 $nearSphere를 사용하므로 구에서 평면 기하학과 거리 계산을 모두 지원하지만 구면 기하학을 사용하는 쿼리는 2dsphere 인덱스를 사용할 때 성능과 정확성이 향상됨
- $near 쿼리 연산 외에도 $geoNear나 특수 명령인 geoNear를 사용해 주변 위치를 쿼리 할 수 있음
- 단, $near 쿼리 연산자는 몽고DB의 확장 솔루션인 샤딩을 사용해 배포된 컬렉션에서는 작동하지 않음
- geoNear 명령과 $geoNear 집계 연산자를 사용하려면 컬렉션에 2dsphere 인덱스와 2d 인덱스가 최대 1개만 있어야 함
- 반면, $near나 $geoWithin과 같은 공간 정보 쿼리 연산자는 컬렉션이 여러 개의 공간 정보 인덱스를 갖도록 허용
- geoNear 명령과 $geoNear 구문은 둘 다 위치 필드를 포함하지 않으므로 공간 정보 인덱스 제한이 존재하기 때문에 여러 2d 인덱스나 2dsphere 인덱스 간의 선택이 모호해짐
- 공간 정보 쿼리 연산자에는 이러한 제한이 없으며, 위치 필드를 사용해 모호성을 없앰
나. 왜곡
- 구면 기하를 지도에 시각화하면 왜곡이 있는데, 지구와 같은 3차원 구를 평면에 투사하는 특성 때문
다. 레스토랑 검색
예제에서는 뉴욕에 위치한 지역 (https://oreil.ly/rpGna)과 레스토랑 (https://oreil.ly/JXYd-) 데이터셋을 이용해 작업했고 각 컬렉션에 대해 2dsphere 인덱스를 생성했습니다.
라. 데이터 탐색
- mongo 셸 혹은 MongoDB Compass에서 간단한 쿼리 몇 가지를 실행해 보면 이러한 컬렉션의 도큐먼트에 사용되는 스키마를 이해할 수 있음
- 코드에서 neighborhood 도큐먼트는 뉴욕 내 영역에 해당
- 제과점 또한 뉴욕 내 '424 West 43rd Street'에 위치한 Little Pie Company
마. 현재 지역 찾기
- 사용자의 휴대 기기가 정확한 위치 정보를 제공한다고 가정할 때 $geoIntersects를 사용해 사용자가 현재 위치한 지역을 쉽게 찾을 수 있음
- 사용자 위치의 경도 좌표 -73.93414657 그리고 위도 좌표 40.82302903이라고 가정했을 때 GeoJSON 형식의 특수한 $geometry 필드로 점을 지정해 현재 지역을 찾을 수 있음
바. 지역 내 모든 레스토랑 찾기
- 특정 지역 내 레스토랑을 모두 찾는 쿼리도 수행 가능
- mongo 셸에서 다음을 실행해 사용자가 위치한 지역을 조회한 뒤 해당 지역 내 레스토랑 수를 계산할 수 있음
사. 범위 내에서 레스토랑 찾기
- 특정 지점으로부터 지정된 거리 내에 있는 레스토랑을 조회할 수 있음
- "$centerSphere"와 함께 "$geoWithin"을 사용하면 정렬되지 않은 순서로 결과를 반환하며, "$maxDistance"와 함께 "$nearSphere"를 사용하면 거리 순으로 정렬된 결과를 반환함
- 원형 지역 내 레스토랑을 찾으려면 "$centerSphere"와 함께 "$geoWithin"을 사용
- "$centerSphere"는 중심과 반경을 라디안으로 지정해 원형 영역을 나타내는 몽고DB 전용 구문
- "$geoWithin"은 도큐먼트를 특정 순서로 반환하지 않으므로 거리가 가장 먼 도큐먼트를 먼저 반환할 수도 있음
다음은 사용자로부터 5마일 이내에 있는 레스토랑을 모두 찾는 쿼리입니다.
- "$centerSphere"의 두 번째 인자는 반지름을 라디안 값으로 받음
- 쿼리는 거리를 지구의 대략적인 적도 반경인 3963.2마일로 나누어 라디안으로 변환함
1.3 복합 공간 정보 인덱스
- 공간 정보 인덱스는 다른 인덱스 종류와 마찬가지로 다른 필드와 묶음으로써 더 복잡한 쿼리를 최적화할 수 있음
- 앞서 살펴본 "레스토랑 찾기" 쿼리에도 적용됨
- 앞선 예제에서는 공간 정보 인덱스만을 사용해 헬스 키친 내 모든 필드로 필터링했지만, 다른 필드와 묶으면 "restaurants"나 "pizza" 필드로 필터링 가능
1.4 2d 인덱스
- 비디오 게임, 지도, 시계역 데이터 등과 같은 비구체에는 "2dsphere" 대신 "2d" 인덱스를 사용
- "2d" 인덱스는 지형이 구체가 아니라 완전히 평평한 표면이라고 가정
- 극 주변은 왜곡이 매우 심하기 때문에 구체에 "2d"를 사용해서는 안됨
db.hyrule.createIndex({"tile": "2d})
- 도큐먼트는 "2d" 인덱스 필드에 요소가 2개인 배열을 사용하며, 배열 요소는 각각 경도 좌표와 위도 좌표를 나타냄
- GeoJSON 데이터를 저장하려면 2d 인덱스를 사용하지 않는 것을 권장
- 2d 인덱스는 점만 인덱싱할 수 있음
- 점의 배열을 저장할 수는 있지만 정확하게는 선이 아닌 점의 배열을 저장하는데 이는 특히 "$geoWithin" 쿼리에서 큰 차이가 있음
- 도로를 점의 배열로 저장했다면, 점 하나가 주어진 도형 안에 있으면 도큐먼트가 "$geoWithin"과 일치하지만 점들로 이루어진 선은 도형에 완전히 포함되지 않음
- 2d 인덱스는 "$geoWithin", "$nearSphere", 그리고 "$near" 쿼리 셀렉터를 지원함
- "$geoWithin"은 평평한 표면에 정의된 영역 내 점을 쿼리 하는 데 사용
- 직사각형, 다각형, 원, 그리고 구 안에 있는 모든 점을 쿼리 할 수 있으며, "$geometry" 연산자를 사용해 GeoJSON 객체를 지정
- 주변에 있는 점을 쿼리 하려면 "$near"를 사용
- 근접 쿼리는 특정 지점으로부터 가장 가까운 좌표 쌍을 포함하는 도큐먼트를 반환하고 결과를 거리 순으로 정렬
- 예제에서는 hyrule 컬렉션 내 모든 도큐먼트를 지점 (20, 21)로부터 거리가 가까운 순으로 찾음
db.hyrule.find({"tile": {"$near": [20, 21]}})
2. 전문 검색을 위한 인덱스
- 몽고DB의 text 인덱스는 전문 검색의 요구 사항을 지원함
- 아파치 루씬을 활용하는 몽고DB 아틀라스 전무 검색 인덱스와는 다른 인덱스
- 애플리케이션 사용자가 제목, 설명 등 컬렉션 내 필드의 텍스트와 일치시키는 키워드 쿼리를 하게 하려면 text 인덱스를 활용하는 것을 권장
- 정규 표현식으로도 문자열을 쿼리 할 수 있지만 큰 텍스트 블록을 검색할 경우 쿼리 속도가 느리며, 문법과 같은 언어 특성을 반영하기도 쉽지 않음
- text 인덱스는 텍스트를 빠르게 검색하는 기능을 제공하며, 언어에 적합한 토큰화, 정지 단어, 형태소 분석 등 일반적인 검색 엔진 요구 사항을 지원함
- text 인덱스에서 필요한 키의 개수는 인덱싱 되는 필드의 단어 개수에 비례하기 때문에 시스템 리소스가 많이 소비될 수 있음
- 따라서 인덱스 생성이 애플리케이션 성능에 부정적인 영향을 미치지 않을 때 생성해야 하며, 가능하면 백그라운드에서 인덱스를 구축해야 함
- 다른 인덱스와 마찬가지로, 우수한 성능을 보장하려면 생성하는 모든 text 인덱스가 램에 맞는지 확인해야 함
- 컬렉션에 쓰기 작업을 수행하려면 모든 인덱스를 갱신해야 함
- 텍스트 검색을 사용하면 문자열이 토큰화되고, 형태소화되며, 인덱스는 잠재적으로 여러 위치에서 갱신됨
- 이에 따라 text에 대한 쓰기는 일반적으로 단일 필드, 복합 또는 다중키 인덱스에 대한 쓰기보다 더 많은 비용이 발생하므로 text로 인덱싱 된 컬렉션에서는 쓰기 성능이 다른 컬렉션에서보다 떨어지는 경향이 있음
- 또한 샤딩을 하면 데이터 이동 속도가 느려지며, 모든 텍스트는 생 샤드로 마이그레이션 될 때 다시 인덱싱 돼야 함
2.1 텍스트 인덱스 생성
- 위키피디아 문서 컬렉션에 인덱싱 한다고 가정했을 때 텍스트에 검색을 실행하려면 먼저 text 인덱스를 생성해야 함
- "title"과 "body" 필드 내 용어를 기반으로 인덱스 생성한다고 가정
- 키에 순서가 있는 일반적인 복합 인덱스와 달리, 기본적으로 각 필드는 text 인덱스에서 동등하게 고려되는데 가중치를 지정하면 몽고DB가 각 필드에 지정하는 상대적 중요도를 제어할 수 있음
db.articles.createIndex({"title": "text", "body": "text"}, {"weights": {"title": 3, "body": 2}})
- 인덱스를 한 번 생성한 뒤에는 삭제하지 않는 한 가중치를 변경할 수 없음
- 따라서 사용 데이터에 인덱스를 생성하기 전에 샘플 데이터 셋에 가중치를 적용해 보는 것을 권장
2.2 텍스트 검색
- "$text"는 공백과 구두점을 구분 기호로 사용해 검색 문자열을 토큰화하며, 검색 문자열에서 모든 토큰의 논리적 OR을 수행
- i.g. 다음처럼 쿼리 하면 "impact"나 ".crater" 또는 "lunar"라는 용어가 포함된 기사를 모두 찾을 수 있음
- 역서 인덱스는 문서 제목과 본문 내 용어를 기반으로 하므로, 쿼리는 두 필드 중 하나에 해당 용어를 포함하는 도큐먼트와 일치함
ㅇ
부연 설명
- 예제에서는 쿼리를 실행한 방식에 두 가지 문제점이 있음
- 첫 번째는 몽고DB가 "impact", "crater", "lunar"의 논리적 OR를 사용해 쿼리를 실행한다는 점을 고려하면 쿼리가 매우 광범위하다는 점
- 두 번째 문제는 텍스트 검색이 기본적으로 결과를 관련성에 따라 정렬하지 않는다는 점
구문을 사용하면 앞서 언급한 쿼리 자체의 문제를 해결할 수 있습니다.
- 텍스트를 큰따옴표로 묶어서 정확히 일치하는 구문을 검색할 수 있음
- i.g. 다음은 "impact crater"라는 구문이 포함된 도큐먼트를 모두 찾으며 몽고DB는 해당 쿼리를 "impact crater" AND "lunar"로 처리
다음 예제에서 몽고DB는 "impact crater" AND {"lunar" OR "meter"}로 쿼리를 실행합니다.
- 몽고DB는 검색 문자열 내 개별 용어로 구문의 논리적 AND를 수행하고, 개별 용어마다 논리적 OR를 서로 수행함
쿼리의 개별 용어 사이에 논리적 AND를 실행하려면 각 용어를 큰따옴표로 묶어 구문으로 처리해야 합니다.
- 다음 쿼리는 "impact crater", "lunar", "meteor"를 모두 포함하는 도큐먼트를 반환함
- "impact crater" AND "lunar" AND "meteor"
텍스트 쿼리를 사용하면 각 쿼리 결과에 메타데이터가 연결됩니다.
- 메타데이터는 $meta 연산자를 사용해 명시적으로 투영하지 않는 한 쿼리 결과에 표시되지 않기 때문에 제목 외에도 각 도큐먼트에 대해 계산된 관련성 스코어를 투영함
- 관련성 스코어는 "textScore"라는 메타 데이터 필드에 저장됨
- 예제에서는 "impact crater" AND "lunar"를 사용했던 쿼리를 다시 살펴보며 이제 결과마다 제목과 예상되는 관련성 점수를 확인 가능
2.3 전문 검색 최적화
- 전문 검색을 최적화하는 방법은 두 가지
- 다른 기준으로 검색 결과를 좁힐 수 있다면 복합 인덱스를 생성할 때 다른 기준을 첫 번째로 두고 전문 필드를 그다음으로 두는 방법
- 다른 기준을 뒤쪽에 두어 사용할 수도 있음
가. 첫 번째 방법
- 전문 인덱스를 "date"에 따라 몇 개의 작은 트리 구조로 쪼개며, 이를 파티셔닝이라고 함
- 전문 인덱스를 분할해 특정 날짜에 대한 전문 검색을 훨씬 빨리 할 수 있음
db.blog.createIndex({"date": 1, "post": "text"})
나. 두 번째 방법
- "author"와 "post" 필드만 반환한다면 두 필드에 대해 복합 인덱스를 생성할 수 있음
db.blog.createIndex({"post": "text", "author": 1})
2.4 다른 언어로 검색하기
- 도큐먼트가 입력되면 몽고DB는 인덱스 필드를 살펴보고 기본 구성단위로 줄여가며 각 단어의 형태소를 분석함
- 하지만 언어에 따라 형태소 분석 방법이 상이하므로 인덱스나 도큐먼트가 어떤 언어로 쓰였는지 명시해야 함
- text 인덱스에는 "default_language" 옵션을 지정할 수 있고 기본값은 "english"로 설정되지만 다양한 언어로 설정 가능
3. 제한 컬렉션
- 몽고DB의 `일반적인` 컬렉션은 동적으로 생성되고 추가적인 데이터에 맞춰 크기가 자동으로 늘어나지만 `제한 컬렉션`은 미리 생성되고 크기가 고정됨
- 제한 컬렉션은 환형 큐처럼 동작하기 때문에 삽입되는 시점에 빈 공간이 없으면 가장 오래된 도큐먼트가 지워지고 새로운 도큐먼트가 해당 자리를 차지함
- 제한 컬렉션은 새로운 도큐먼트가 입력되면 자동으로 가장 오래된 도큐먼트부터 지움
- 다음 작업들은 제한 컬렉션에서 허용되지 않음
- 도큐먼트는 앞서 설명한 오래된 순으로 자동으로 지우는 작업 외 삭제 불가능
- 도큐먼트 크기가 커지도록 하는 갱신도 허용되지 않음
- 또한 샤딩될 수 없음
- 대부분의 몽고DB 컬렉션의 접근 방식과 달리 제한 컬렉션은 데이터가 디스크의 고정된 영역에 순서대로 기록됨
- 따라서 회전 디스크에서 쓰기를 다소 빠르게 수행할 수 있음
- 일반적으로 몽고DB TTL 인덱스는 와이어드타이거 스토리지 엔진에서 더 나은 성능을 발휘하므로 제한 컬렉션보다 권장됨
- TTL 인덱스는 날짜 유형 필드 값과 인덱스의 TTL 값을 기반으로 일반 컬렉션에서 데이터가 만료되고 제거됨
- 제한 컬렉션은 유연성이 부족한 대신 로깅에는 나름 유용함
- 단, 사용자는 컬렉션을 생성할 때 크기를 설정할 수는 있지만, 데이터가 오래된 순으로 지워질 때 제어할 수 없음
3.1 제한 컬렉션 생성
- 일반 컬렉션과 달리 제한 컬렉션은 사용되기 전에 명시적으로 생성돼야 하며 생성하려면 create 명령어를 사용
- 아래 예제는 10만 바이트 고정 크기인 제한 컬렉션을 생성하며 도큐먼트 수를 100개로 제한
db.createCollection("my_collection", {"capped": true, "size": 100000, "max": 100});
- 제한 컬렉션은 일단 생성되면 변경할 수 없으며 속성 변경을 위해서는 삭제 후 재생성해야 하므로 크기가 큰 컬렉션은 생성하기 전에 신중히 검토할 필요가 있음
- 제한 컬렉션을 생성하는 또 다른 방법은 일반 컬렉션을 제한 컬렉션으로 변환하는 방법
- covertToCapped 명령어를 사용해 실행 가능
- 아래 예제는 test 컬렉션을 1만 바이트 크기 제한 컬렉션으로 변환
db.runCommand({"covertToCapped": "test", "size": 10000});
3.2 꼬리를 무는 커서
- 꼬리를 문는 커서는 결과를 모두 꺼낸 후에도 종료되지 않는 특수한 형태의 커서
- `tail -f`와 비슷하게 결과를 지속적으로 꺼내는 기능을 수행
- 커서는 결과를 다 꺼내도 종료되지 않으므로 컬렉션에 데이터가 추가되면 새로운 결과를 바로 꺼낼 수 있음
- 일반 컬렉셔에서는 입력 순서가 추적되지 않기 때문에 꼬리를 무는 커서는 제한 컬렉션에만 사용
- 꼬리를 무는 커서는 도큐먼트가 제한 컬렉션에 입력되면 도큐먼트를 처리하는 데 사용
- mongo 셸에서는 꼬리를 무는 커서를 사용할 수 없지만 PHP에서는 다음과 같이 사용
- 커서는 시간이 초과되거나 누군가가 쿼리 작업을 중지할 때까지는 결과를 처리하거나 다른 결과가 더 도착할 때까지 대기
4. TTL 인덱스
- 오래된 순 삭제 시스템을 더 유연하게 만들기 위해 TTL 인덱스를 이용해 각 도큐먼트에 유효 시간을 설정할 수 있음
- 도큐먼트는 미리 설정한 시간에 도달하면 삭제됨
- 해당 인덱스는 세션 스토리지와 같은 문제를 캐싱하는 데 유용함
- createIndex의 두 번째 인자에 `expiredAfterSeconds` 옵션을 명시해 TTL 인덱스를 생성할 수 있음
- 아래 예제는 `lastUpdated` 필드에 24시간 TTL 인덱스를 생성
- 활동 중인 세션이 삭제되는 것을 방지하려면 활동이 있을 때마다 "lastUpdated" 필드를 현재 시간으로 갱신하면 됨
db.sessions.createIndex({"lastUpdated": 1}, {"expiredAfterSeconds": 60 * 60 * 24});
- 몽고DB는 TTL 인덱스를 매분마다 청소하므로 초 단위로 신경 쓸 필요 없고 collMod 명령어를 이용해 `expiredAfterSeconds`를 변경할 수 있음
db.runCommand({"collMod": "someapp.cache", "index": {"keyPattern": {"lastUpdated": 1}, "expiredAfterSeconds": 3600}});
5. GridFS로 파일 저장하기
- GridFS는 몽고DB에 대용량 이진 파일을 저장하는 메커니즘
- 파일을 저장할 때 GridFS를 고려하는 이유는 다음과 같음
- 아키텍처 스택 단순화: 이미 몽고DB를 사용 중이라면 파일 스토리지를 위한 별도의 도구 대신 GridFS를 사용하면 됨
- 기존의 복제나 자동 샤딩 이용 가능: 파일 스토리지를 위한 장애 조치와 분산 확장에 용이함
- 파일을 저장할 때 특정 파일 시스템이 갖는 문제 회피 가능: GridFS는 같은 디렉터리에 대량의 파일을 저장해도 문제없음
- 반면, GridFS를 사용함에 따라 단점도 있음
- 성능이 느림: 몽고DB에서 파일에 접근하면 파일 시스템에서 직접 접근할 때만큼 빠르지 않음
- 도큐먼트 수정 불가: 수정하기 위해서는 도큐먼트 전체를 삭제하고 다시 저장하는 방법 밖에 없음
5.1 GridFS 시작하기: mongofiles
- mongofiles 유틸리티로 쉽게 GridFS를 설치하고 운영 가능
- mongofiles는 모든 몽고DB 배포판에 포함되며 GridFS에서 파일을 올리고, 받고, 목록을 출력하고, 검색하고, 삭제할 때 등에 사용
- put 연산은 파일 시스템으로부터 파일을 받아 GridFS에 추가
- list 연산은 GridFS에 올린 파일 목록을 보여줌
- get 연산은 put의 반대 연산으로 GridFS에서 파일을 받아 파일 시스템에 저장
- search 연산은 파일명으로 GridFS에 저장된 파일을 검색
- delete 연산은 GridFS에 저장된 파일을 삭제
5.2 몽고DB 드라이버로 GridFS 작업하기
- 모든 클라이언트 라이브러리는 GridFS API를 가짐
- i.g. 몽고DB를 지원하는 파이썬 드라이버인 파이몽고를 사용해서 다음처럼 mongofiles로 작업을 수행할 때와 동일한 일련의 작업을 수행 가능
5.3 내부 살펴보기
- GridFS는 파일 저장을 위한 간단한 명세이며 일반 몽고DB 도큐먼트를 기반으로 만들어짐
- 몽고DB 서버는 GridFS 요청을 처리하면서 '특별한 작업'을 거의 하지 않으며, 모든 작업은 클라이언트 쪽의 드라이버 도구가 처리함
- GridFS의 기본 개념은 대용량 파일을 청크로 나눈 뒤 각 청크를 도큐먼트로 저장할 수 있다는 것
- 몽고DB는 도큐먼트에 이진 데이터를 저장할 수 있으므로 청크에 대한 저장 부하를 최소화할 수 있음
- 파일의 청크를 저장하는 작업 외에도, 여러 청크를 묶고 파일의 메타데이터를 포함하는 단일 도큐먼트를 만듦
- GridFS의 청크는 자체 컬렉션에 저장되며 청크 컬렉션 내 각 도큐먼트의 구조는 다음과 같이 매우 간단함
- "files_id": 청크에 대한 메타데이터를 포함하는 파일 도큐먼트의 "_id"
- "n": 다른 청크를 기준으로 하는 파일 내 청크의 위치
- "data": 파일 내 청크의 크기
- 각 파일의 메타데이터는 기본적으로 별도의 컬렉션인 fs.files에 저장됨
- files 컬렉션 내 각 도큐먼트는 GridFS에서 하나의 파일을 나타내며, 해당 파일과 관련된 어떤 메타데이터든 포함할 수 있음
- 사용자 정의 키 외에도 GridFS 명세에서 강제하는 키가 몇 개 더 있음
- "_id": 파일의 고유 ID로 각 청크에서 "file_id" 키의 값으로 저장됨
- "length": 파일 내용의 총 바이트 수
- "chunkSize": 파일을 구성하는 각청크의 크기이며 단위는 바이트
- "uploadDate": GridFS에 파일이 저장된 시간
- "md5": 서버에서 생성된 파일 내용의 MD5 체크썸 (파일이 제대로 올라갔는지 확인하는 용도)
참고
몽고DB 완벽 가이드 3판 - 한빛미디어
'DB > 몽고DB 완벽 가이드 3판' 카테고리의 다른 글
[8장] 트랜잭션 (0) | 2025.04.16 |
---|---|
[7장] 집계 프레임워크 (0) | 2025.04.12 |
[5장] 인덱싱 (2) | 2025.04.04 |
[4장] 쿼리 (0) | 2025.03.29 |
[3장] 도큐먼트 생성, 갱신, 삭제 (1) | 2025.03.28 |