flat_object 필드 타입
flat_object 필드 타입
도입 2.7
OpenSearch에서는 문서를 색인하기 전에 매핑을 지정할 필요가 없어요. 매핑을 지정하지 않으면 OpenSearch는 동적 매핑을 사용해 문서의 모든 필드와 하위 필드를 자동으로 매핑해요. 로그 같은 문서를 수집할 때 모든 필드의 하위 필드 이름과 타입을 미리 알 수 없을 수 있어요. 이 경우 동적으로 새 하위 필드를 매핑하면 필드 수가 계속 늘어나 클러스터 성능을 저하시킬 수 있는 "mapping explosion(매핑 폭증)"이 빠르게 발생할 수 있어요.
flat object 필드 타입은 JSON 객체 전체를 문자열로 취급해 이 문제를 해결해요. JSON 객체 안의 하위 필드는 표준 점 표기법(dot path notation)으로 접근할 수 있지만, 빠른 조회를 위해 인덱싱되지는 않아요.
점 표기법의 최대 필드 값 길이는 224 − 1이에요.
flat object 필드 타입은 다음과 같은 장점을 제공해요.
- 효율적인 읽기: 조회 성능이 keyword 필드와 유사해요.
- 메모리 효율성: 모든 하위 필드의 인덱싱 없이 복잡한 JSON 객체 전체를 하나의 필드에 저장하면 인덱스의 필드 수가 줄어들어요.
- 공간 효율성: OpenSearch는 flat object의 하위 필드에 대해 역색인(inverted index)을 만들지 않아 공간을 절약해요.
- 마이그레이션 호환성: 유사한 flat 타입을 지원하는 시스템에서 OpenSearch로 데이터를 마이그레이션할 수 있어요.
필드와 그 하위 필드를 대부분 읽기 전용으로 사용하고 검색 기준으로는 사용하지 않을 때(하위 필드가 인덱싱되지 않으므로) flat object로 매핑해요. flat object는 필드 수가 많거나 키를 미리 알 수 없는 객체에 유용해요.
flat object는 점 표기법이 있거나 없는 정확한 매칭 쿼리를 지원해요. 지원되는 쿼리 타입의 전체 목록은 지원되는 쿼리를 참조하세요.
문서에서 중첩 필드의 특정 값을 검색하는 것은 인덱스 전체 스캔이 필요할 수 있어 비용이 많이 드는 작업이므로 비효율적일 수 있어요.
flat object는 다음을 지원하지 않아요.
- 타입별 파싱.
- 수치 비교 또는 수치 정렬 같은 수치 연산.
- 텍스트 분석.
- 하이라이팅.
- 점 표기법을 사용한 하위 필드 집계.
- 하위 필드 필터링.
출처: 문서
본문
지원되는 쿼리
flat object 필드 타입은 다음 쿼리를 지원해요.
- Term
- Terms
- Terms set
- Prefix
- Range
- Match
- Multi-match
- Query string
- Simple query string
- Exists
- Wildcard
제한 사항
OpenSearch 2.7에서 flat object에 적용되는 제한 사항은 다음과 같아요.
- flat object는 open 파라미터를 지원하지 않아요.
- 하위 필드의 값을 검색할 때 Painless 스크립트와 와일드카드 쿼리는 지원되지 않아요. 자세한 내용은 Painless 스크립트 언어를 참조하세요.
이 기능은 향후 릴리스에서 계획되어 있어요.
flat object 사용하기
다음 예제는 필드를 flat object로 매핑하고, flat object 필드가 있는 문서를 색인하며, 그러한 문서에서 flat object의 리프 값을 검색하는 방법을 보여줘요.
먼저 issue의 타입이 flat_object인 인덱스의 매핑을 만들게요.
PUT /test-index/
{
"mappings": {
"properties": {
"issue": {
"type": "flat_object"
}
}
}
}
다음으로 flat object 필드가 있는 두 문서를 색인해요.
PUT /test-index/_doc/1
{
"issue": {
"number": "123456",
"labels": {
"version": "2.1",
"backport": [
"2.0",
"1.3"
],
"category": {
"type": "API",
"level": "enhancement"
}
}
}
}
PUT /test-index/_doc/2
{
"issue": {
"number": "123457",
"labels": {
"version": "2.2",
"category": {
"type": "API",
"level": "bug"
}
}
}
}
flat object의 리프 값을 검색하려면 GET 또는 POST 요청을 사용해요. 필드 이름을 몰라도 flat object 전체에서 리프 값을 검색할 수 있어요. 예를 들어 다음 요청은 버그로 분류된 모든 이슈를 검색해요.
GET /test-index/_search
{
"query": {
"match": {"issue": "bug"}
}
}
또는 검색할 하위 필드 이름을 안다면 필드 경로를 점 표기법으로 제공할 수 있어요.
GET /test-index/_search
{
"query": {
"match": {"issue.labels.category.level": "bug"}
}
}
두 경우 모두 응답은 동일하며 문서 2를 포함해요.
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.0303539,
"hits": [
{
"_index": "test-index",
"_id": "2",
"_score": 1.0303539,
"_source": {
"issue": {
"number": "123457",
"labels": {
"version": "2.2",
"category": {
"type": "API",
"level": "bug"
}
}
}
}
}
]
}
}
접두어 쿼리를 사용해 2.로 시작하는 버전의 모든 이슈를 검색할 수 있어요.
GET /test-index/_search
{
"query": {
"prefix": {"issue.labels.version": "2."}
}
}
범위 쿼리를 사용해 버전 2.0~2.1의 모든 이슈를 검색할 수 있어요.
GET /test-index/_search
{
"query": {
"range": {
"issue": {
"gte": "2.0",
"lte": "2.1"
}
}
}
}
하위 필드를 flat object로 정의하기
JSON 객체의 하위 필드를 flat object로 정의할 수 있어요. 예를 들어 다음 쿼리를 사용해 issue.labels를 flat_object로 정의할 수 있어요.
PUT /test-index/
{
"mappings": {
"properties": {
"issue": {
"properties": {
"number": {
"type": "double"
},
"labels": {
"type": "flat_object"
}
}
}
}
}
}
issue.number는 flat object의 일부가 아니므로 이를 사용해 문서를 집계하고 정렬할 수 있어요.
관련 문서
- 객체 비활성화 (Disable objects)
출처: 문서