카테고리 없음

[MongoDB] 몽고DB 후다닥 시작하기 - 5 (인덱스)

김크리 2022. 6. 29. 22:20

공간 정보 인덱스

- 몽고DB는 2sphere와 2d라는 공간 정보 인덱스를 가진다

  - 2shpere 인덱스 : WGS84좌표계를 기반으로 지표면을 모델링 하는 구면 기하학으로 작동, 지구의 형태를 고려함으로 2d인덱스보다 정확한 거리 계산이 가능하다. GeoJSON형식으로 기하 구조를 지정할 수 있다. 점은 경도/위도 요소를 갖는 배열로 표현된다.

  - 2d 인덱스 : 2차원 평면의 점에 적합한 인덱스

- 공간 정보 쿼리는 교차(intersection), 포함(within), 근접(nearness)라는 세가지 유형이 있다. 찾을 항목을 {"$geometry":geoJsonDesc}와 같은 GeoJSON 객체로 지정한다.

- $near 연산자는 정렬을 포한한 유일한 공간정보 연산자 이다. 항상 거리  가 가장 가까운 곳부터 가장 먼 곳 순으로 반환된다.

- 공간정보 인덱스를 사용하여 컬렉션에서 공간 쿼리(spatial query)를 효율적으로 실행할 수 있다.

- $geoWithin, $geoIntersects, $geoNear 라는 공간 정보 연산자가 사용하는 기하 구조 유형을 알 수 있다. 각 매개변수와 연산자에 따라 지원하는 구면, 평면을 구분 할 수 있다.

- 2d 인덱스는 구(sphere)에서 평면 기하학과 거리 계산을 모두 지원한다. 하지만, 구면 기하학을 사용하는 쿼리는 2dsphere 인덱스를 사용할 때 성능과 정확성이 향상된다.

- $geoNear 연산자는 집계 연산자(Aggregation operator)이다.

- 구면 기하는 지도에 시각화 하면 왜곡이 있다. 

 

전문 검색을 위한 인덱스

- 몽고DB의 text 인덱스는 전문 검색의 요구 사항을 지원한다. 

  - 제목, 설명 등 컬렉션 내의 필드의 텍스트와 일치시키는 키워드 쿼리를 하기 위해서는 text 인덱스를 사용하자.

  - text인덱스는 테스트를 빠르게 검색하는 기능을 제공하며, 언어에 적합한 토큰화, 정지단어, 형태소 분석 등 일반적인 검색 엔진 요구사항을 지원한다.

  - text인덱스에서 필요한 키의 개수는 인덱신되는 필드의 단어 개수에 비례한다.

  - text 인덱스는 잠재적으로 여러 위치에서 갱신되므로 쓰기 성능이 다른 컬렉션에서 떨어지는 경향이 있다. 또한, 샤딩시 데이터 이동속도가 느리고 모든 텍스트는 새 샤드로 마이그래이션 될 때까지 다시 인덱싱 되어야한다.

  - text 인덱스는 필드 내 용어 기반으로 인덱스를 생성한다. 가중치 등 설정이 가능하다.

# text 인덱스 생성
# title, body필드 기반으로 생성
# 가중치를 3, 2로 준다. 가중치는 인덱스 생성 후 변경 할 수 없다.
> db.articles.createIndex({"title":"text","body":"text"}, {"weights":{"title":3,"body":2})

  - $text 쿼리 연산자를 사용하여 text 인덱스가 있는 컬렉션에 텍스트 검색을 수행할 수 있다.

- 전문 검색은 파티셔닝 혹은 복합 인덱스에 대한 설정 등으로 검색 최적화를 할 수 있다.

제한 컬렉션

- 미리 생성되어 크기가 고정된 컬렉션을 제한 컬렉션이라고 한다.

- 제한 컬렉션에 입력을 시도하면 환형 큐 처럼 동작하게 된다. (FILO)

- 유연성이 부족하지만 로깅에는 유용하다.

# 100개의 도큐먼트 제한 컬렉션 생성
> db.createCollection(${collection_name",{"capped":true, "size":10000, "max":100});

# 기존 컬렉션을 제한 컬렉션으로 변환
> db.runCommand({"convertToCapped": ${collection_name}, "size":10000});

# 제한 컬렉션을 기존 컬렉션으로 변환
# 삭제 외의 방법은 없다.

- 꼬리를 무는 커서(tailable cursor) 는 결과를 모두 꺼낸 후에 종료되지 않는 특수한 커서이다

  - 컬렉션에 데이터가 추가 되면 새로운 결과를 바로 꺼낼 수 있다. 이는 제한 컬렉션에서만 사용이 가능하다.

아틀라스 전문 검색 인덱스(atlas full-text search index)

- 아파치 루씬(apache lucene)을 활용하여 추가적인 검색 기능을 구현한다.

TTL 인덱스

- 제한 컬렉션은 내용이 덮어쓰일때 제어할 수 없다. 오래된 순 삭제 시스템에 유연하게 만들기 위해서 TTL 인덱스를 사용한다.

- TTL인덱스는 각 토큐먼트에 유효 시간을 설정할 수 있다.

- TTL인덱스는 세션 스토리지와 같은 문제를 캐싱하는데 유용하다.

- TTL인덱스는 하나의 컬렉션에 여러개 가질 수 있다. 복합 인덱스는 될 수 없지만 일반 인덱스처럼 사용될 수 있다.

#TTL 인덱스 생성
> db.runCommand({"colMod":"someapp.cache"
, "index":{"KeyPathhern":...{"lastUpdated":1}, "expireAfterSeconds":3600}});

GridFS

- GridFS는 몽고 DB에 대용량 이진 파일(Binary file)을 저장하는 매커니즘이다.

- 별도의 파일 스토리지 도구 대신 GridFS를 사용하여 아키텍쳐 스택을 단순화 할 수 있다.

- 몽고DB에 복제나 자동 샤딩을 이용하여 파일 스토리지를 위한 장애 조치와 분산 확장이 쉽다.

- 파일 시스템에 직접 접근 하는 것보다 느리다.

- 도큐먼트를 수정하려면 도큐먼트를 전체 삭제하고 저장해야한다.

- 성능이 느리다.

- 파일을 여러개의 도큐먼트로 저장하므로 한 파일에 모든 청크(chunk)를 걸 수 없다.

- 대용량 파일을 저장할 때 일반적으로 최선의 매커니즘이다.

 

GridFS 시작하기 : mongofiles

- mongofile 유틸리티로 GridFS을 설치하고 운영할 수 있다. 해당 유틸리티는 몽고DB 배포판에 포함되어있다.

https://www.mongodb.com/try/download/database-tools?tck=docs_databasetools 

# 파일을 GridFS 추가
> mongofiles put ${파일명}

# 추가된 파일 확인
> mongofiles list

# 파일 받아오기
> mongofiles get ${파일명}

- GridFS는 파일 저장을 위한 명세이며 몽고DB ehzbajsxm rlqkddmfh aksemfdjwu dlTek.

- 대용량 파일을 청크로 나눈 후 각 청크를 도큐먼트로 저장할 수 있다.

GridFS의 청크(chunk)

- 자체 컬렉션에 저장된다.

{
	"_id":ObjectId("..."),
    # 다른 청크를 기준으로 하는 청크의 위치
	"n":0,
    # 파일 내 청크의 크기(바이트)
	"data":BigData("..."),
    # 청크에 대한 메타데이터를 포함하는 파일 도큐먼트의 _id
	"files_id":ObjectId("..."),
}

- 각 파일의 메타데이터는 기본적으로 별도의 컬렉션인 fs.files에 저장된다.

- 사용자 정의 키 외에 GridFS 명세에 강제하는 키가 있다.

  - _id

  - length

  - chunkSize

  - uploadDate

  - md5 (파일내용의 체크썸)

# 저장된 파일 명 목록 얻기
> db.fs.files.distinct("filename")

참고

도서 - 몽고DB 완벽 가이드 3판