Elastic/Elasticsearch: Nested 필드 타입
설명
- 배열 형태의 데이터에 대해 개별 query 및 aggregations을 하기 위한 필드 타입
테스트
- 데이터
PUT index_1/_doc/1
{
"array_1": [
{
"name": "name 1",
"date": "2021/01/01 01:00:00",
"array_2": [
{
"field_1": "1",
"field_2": 1
},
{
"field_1": "2",
"field_2": 2
}
]
}
]
}
- Nested를 지정하지 않은 경우
- request
GET index_1/_search
{
"query": {
"range": {
"array_1.date": {
"gte": "2021/01/01 01:00:00",
"lt": "2021/01/01 01:05:00",
"format": "yyyy/MM/dd HH:mm:ss"
}
}
},
"size": 0,
"aggs": {
"name": {
"terms": {
"field": "array_1.name.keyword"
},
"aggs": {
"array_2-field_1": {
"terms": {
"field": "array_1.array_2.field_1.keyword"
},
"aggs": {
"array_2-field_2": {
"stats": {
"field": "array_1.array_2.field_2"
}
}
}
}
}
}
}
}
- response
- terms를 지정하였음에도 모든 field_2에 대해 연산 수행
{
"took": 3,
"timed_out": false,
"_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 },
"hits":
{
"total": { "value": 1, "relation": "eq" },
"max_score": null,
"hits": [],
},
"aggregations":
{
"name":
{
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets":
[
{
"key": "name 1",
"doc_count": 1,
"array_2-field_1":
{
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets":
[
{
"key": "1",
"doc_count": 1,
"array_2-field_2":
{
"count": 2,
"min": 1.0,
"max": 2.0,
"avg": 1.5,
"sum": 3.0,
},
},
{
"key": "2",
"doc_count": 1,
"array_2-field_2":
{
"count": 2,
"min": 1.0,
"max": 2.0,
"avg": 1.5,
"sum": 3.0,
},
},
],
},
},
],
},
},
}
- Nested를 지정한 경우
- 정적 매핑
PUT index_1
{
"mappings": {
"properties": {
"array_1": {
"type": "nested",
"properties": {
"array_2": {
"type": "nested",
"properties": {
"field_1": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"field_2": {
"type": "long"
}
}
},
"date": {
"type": "date",
"format": "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
- request
GET index_1/_search
{
"query": {
"nested": {
"path": "array_1",
"query": {
"range": {
"array_1.date": {
"gte": "2021/01/01 01:00:00",
"lt": "2021/01/01 01:05:00",
"format": "yyyy/MM/dd HH:mm:ss"
}
}
}
}
},
"size": 0,
"aggs": {
"nested-array_1": {
"nested": {
"path": "array_1"
},
"aggs": {
"name": {
"terms": {
"field": "array_1.name.keyword"
},
"aggs": {
"nested-array_2": {
"nested": {
"path": "array_1.array_2"
},
"aggs": {
"array_2-field_1": {
"terms": {
"field": "array_1.array_2.field_1.keyword"
},
"aggs": {
"array_1-field_2": {
"stats": {
"field": "array_1.array_2.field_2"
}
}
}
}
}
}
}
}
}
}
}
}
- response
{
"took": 2,
"timed_out": false,
"_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 },
"hits":
{
"total": { "value": 1, "relation": "eq" },
"max_score": null,
"hits": [],
},
"aggregations":
{
"nested-array_1":
{
"doc_count": 1,
"name":
{
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets":
[
{
"key": "name 1",
"doc_count": 1,
"nested-array_2":
{
"doc_count": 2,
"array_2-field_1":
{
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets":
[
{
"key": "1",
"doc_count": 1,
"array_1-field_2":
{
"count": 1,
"min": 1.0,
"max": 1.0,
"avg": 1.0,
"sum": 1.0,
},
},
{
"key": "2",
"doc_count": 1,
"array_1-field_2":
{
"count": 1,
"min": 2.0,
"max": 2.0,
"avg": 2.0,
"sum": 2.0,
},
},
],
},
},
},
],
},
},
},
}