일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 데이터베이스
- 엘라스틱서치
- 백준
- 그리디알고리즘
- 알고리즘
- spring boot
- 코드
- 자바
- JPA
- Java
- 코딩
- cleancode
- 스프링
- ES
- 애자일프로그래밍
- Elasticsearch
- API
- 애자일기법
- 그리디
- mongoDB
- database
- 클린코드
- Baekjoon
- framework
- 읽기쉬운코드
- 코딩테스트
- 개발
- Spring
- 프레임워크
- 개발자
- Today
- Total
튼튼발자 개발 성장기🏋️
[MongoDB] 특수 인덱스 본문
공간 정보 인덱스
MongoDB는 공간 데이터를 효율적으로 검색하기 위해 2dsphere 인덱스를 지원한다. 이는 지구상의 좌표(경도 및 위도)를 저장하고 검색할 때 사용된다. 공간 정보를 저장할 때는 GeoJSON 형식을 사용하며, 주요 기하 구조는 다음과 같다.
- 점(Point)
{ type: "Point", coordinates: [경도, 위도] }
- 선(LineString)
{ type: "LineString", coordinates: [[경도1, 위도1], [경도2, 위도2], ...] }
- 다각형(Polygon)
{ type: "Polygon", coordinates: [[[경도1, 위도1], [경도2, 위도2], ..., [경도1, 위도1]]] }
참고로 내장객체 내 필드(type과 coordinates)는 변경할 수 없다.
2dsphere 인덱스는 아래와 같이 생성할 수 있다.
db.collection.createIndex({ location: "2dsphere" })
공간 정보 쿼리 유형
MongoDB는 공간 정보를 기반으로 검색하는 다양한 쿼리 연산자를 제공한다. 주요 공간 정보 쿼리 유형은 다음과 같다.
1. 교차: `$geoIntersects`
어떤 지점 또는 도형이 특정 영역과 교차하는지 확인하는 쿼리.
db.collection.find({
"location":{
"$geoIntersects":{
"$geometry":{
"type":"Polygon",
"coordinates":[
"..."
]
}
}
}
})
2. 포함: `$geoWithin`
특정 도형이 지정한 영역 내에 포함되는지 확인하는 쿼리.
db.collection.find({
"location":{
"$geoWithin":{
"$geometry":{
"type":"Polygon",
"coordinates":[
"..."
]
}
}
}
})
3. 근접: `$near`
특정 좌표에서 가까운 위치를 찾는 쿼리.
db.collection.find({
"location":{
"$near":{
"$geometry":{
"type":"Point",
"coordinates":[
"경도",
"위도"
]
},
"$maxDistance":1000
}
}
})
복합 공간 정보 인덱스
공간 정보 필드 외에 다른 필드와 함께 사용할 수 있는 복합 공간 정보 인덱스를 생성할 수 있다. 이 인덱스를 활용하면 특정 지역 내에서 특정 카테고리에 해당하는 데이터를 효율적으로 검색할 수 있다.
db.collection.createIndex({ location: "2dsphere", category: 1 })
2d 인덱스
2d 인덱스는 비디오 게임 지도, 시계열 데이터 등과 같은 평면 좌표계 기반의 데이터를 다룰 때 사용한다.
db.collection.createIndex({ location: "2d" })
전문 검색을 위한 인덱스
MongoDB는 텍스트 기반 검색을 최적화하기 위해 text 인덱스를 제공한다. 이를 통해 특정 필드에서 빠른 텍스트 검색을 수행할 수 있다. [인덱스 #1]과 [인덱스 #2]에서 우리는 완전일치와 정규 표현식을 이용해 문자열을 쿼리했지만 이 방식에는 다소 한계가 있다. 공지사항 내용 등과 같은 큰 텍스트 블록을 검색하면 속도가 느리며 문법과 같은 언어 특성을 반영하기 쉽지 않다. 이르 보완한 것이 text 인덱스라고 보면 된다.
text 인덱스를 만들면 시스템 리소스가 많이 소비되므로 애플리케이션 성능에 부정적인 영향을 미치지 않을 때 생성해야한다. 가능하면 백그라운드에서 구축하는 것을 권장한다. 텍스트 검색 시 문자열이 토큰화되고 형태소화되며 인덱스는 잠재적으로 여러 위치에서 갱신되기 때문에 text 인덱스에 대한 쓰기 작업은 타 인덱스에 대한 쓰기 작업보다 더 많은 리소스를 필요로 한다. 또한 샤딩을 하면 데이터 이동 속도가 느려지며 모든 텍스트는 새 샤드로 마이그레이션 될 때 다시 인덱싱되어야한다.
text 인덱스 생성
MongoDB에서 텍스트 검색을 활성화하려면 text 인덱스를 생성해야 한다.
db.collection.createIndex({ content: "text" })
// 가중치를 부여하여 중요도를 나타낼 수 있다.
db.collection.createIndex(
{ title: "text", description: "text", content: "text" },
{ weights: { title: 3, description: 2, content: 1 } }
)
db.collection.createIndex({ title: "text", description: "text" })
텍스트 검색
MongoDB에서는 $text 연산자를 사용하여 특정 키워드를 포함하는 문서를 검색할 수 있다.
db.collection.find({ $text: { $search: "검색어" } })
$search 연산자는 여러 단어를 검색할 수 있으며, "-제외할단어"를 사용하여 특정 단어를 제외할 수도 있다.
db.collection.find({ $text: { $search: "MongoDB -NoSQL" } })
MongoDB의 $search는 기본적으로 OR 검색을 수행하지만, 여러 단어를 반드시 포함하려면 각각을 따옴표로 묶고 AND를 활용할 수 있다.
예를 들어, 문자열 "MongoDB"와 "튜토리얼"이 포함된 text를 검색하고자 한다면 아래와 같이 쿼리하면 된다.
db.collection.find({ $text: { $search: "\"MongoDB\" \"튜토리얼\"" } })
텍스트 쿼리를 사용하면 각 쿼리 결과에 메타데이터가 연결된다. 메타데이터는 $meta 연산자를 사용해 명시적으로 투영하지 않는 한 쿼리 결과에 표시되지 않는다. 따라서 제목 외에도 각 도큐먼트에 대해 계산된 관련성 스코어를 투영한다.
예를 들어, 관련성 스코어는 "textScore"라는 메타 데이터 필드에 저장된다.
> db.collection.find(
{ $text: { $search: "\"MongoDB\" \"튜토리얼\"" } },
{ score: { $meta: "textScore" } }
).sort({ score: { $meta: "textScore" } })
[
{
"_id": 1,
"title": "MongoDB 튜토리얼 가이드",
"content": "MongoDB는 NoSQL 데이터베이스 중 하나로, 유연한 스키마를 제공합니다.",
"score": 2.5
},
{
"_id": 2,
"title": "튜토리얼: MongoDB 기본 사용법",
"content": "이 문서는 MongoDB를 처음 사용하는 사람들을 위한 튜토리얼입니다.",
"score": 2.3
},
{
"_id": 4,
"title": "MongoDB 인덱스 최적화",
"content": "MongoDB에서 성능을 향상시키는 방법 중 하나는 적절한 인덱스를 설정하는 것입니다.",
"score": 1.8
}
]
전문 검색 최적화
전문 검색을 최적화하는 방법은 두 가지가 있다.
1. 다른 기준으로 검색 결과를 좁힐 수 있다면 복합 인덱스를 생성할 때 다른 기준을 첫 번째로 두고 전문 필드를 그 다음으로 둔다.
db.collection.createIndex({ date: 1, post: "text" })
2. 만약 "author"와 "post" 필드만 반환한다면 두 필드에 대해 아래와 같이 인덱스를 생성할 수 있다.
db.collection.createIndex({ post: "text", "author": 1 })
다국어 지원
MongoDB의 텍스트 검색은 여러 언어를 지원하며, 기본적으로 영어를 사용한다. 언어 설정을 변경하려면 default_language 옵션을 사용할 수 있다.
db.collection.createIndex({ content: "text" }, { default_language: "korean" })
이렇게 하면 한국어 형태소 분석이 적용된 텍스트 검색이 가능하다.
형태소 분석이란 주어진 언어 문장에서 구조를 파악하고, 문장 분할, 분석, 추출, 원형 복원을 거쳐 의미를 갖는 최소 단위인 형태소(morphemes)를 발굴해 내는 과정을 말한다.
'기타 > MongoDB' 카테고리의 다른 글
[MongoDB] 영속성 (0) | 2025.03.23 |
---|---|
[MongoDB] 트랜잭션 (0) | 2025.03.23 |
[MongoDB] 인덱싱 #2 (0) | 2025.03.16 |
[MongoDB] 인덱싱 #1 (0) | 2025.03.15 |
[MongoDB] 도큐먼트 생성, 갱신, 삭제 (0) | 2025.03.06 |