Elasticsearch: 객체 및 중첩 데이터 유형
Elasticsearch는 동적 매핑을 사용하여 작동하기 때문에 인덱스에 대한 매핑을 생성할 필요가 없습니다. 따라서 문서에 삽입하는 내용을 기반으로 데이터 유형을 추론합니다.
매핑은 매우 유연하기 때문에 명시적 매핑과 동적 매핑을 결합할 수도 있습니다. 따라서 명시적인 데이터 유형으로 인덱스를 생성할 수 있으며, 문서를 추가할 때 문서에 새 필드가 있을 수 있으며 Elasticsearch는 해당 유형에 따라 이를 저장합니다.
데이터 유형
Elasticsearch는 short, integer, long, float, double, boolean, date와 같은 많은 프로그래밍 언어에서도 찾을 수 있는 매우 일반적인 데이터 유형을 제공합니다.
객체 데이터 유형
객체 데이터 유형은 Elasticsearch가 JSON 값을 저장하는 방법을 나타냅니다. 기본적으로 모든 문서는 객체이며 중첩 객체를 가질 수 있습니다. 예를 살펴보겠습니다.
PUT /users
{
"mappings": {
"properties": {
"name": {"type": "text"},
"birthday": {"type": "date"},
"address": {
"properties": {
"country": {"type": "text"},
"zipCode": {"type": "text"}
}
}
}
}
}
이렇게 하면
text
필드, date
필드 및 주소를 나타내고 중첩된 object
필드를 포함하는 text
필드가 있는 사용자라는 인덱스가 생성됩니다.여기에 문서를 인덱싱하려면 다음 요청을 할 수 있습니다.
POST /users/_doc/1
{
"name": "Lucas",
"birthday": "1990-09-28",
"address": {
"country": "Brazil",
"zipCode": "04896060"
}
}
Elasticsearch는 Apache Lucene 위에서 실행되기 때문에 이러한 개체가 실제로 내부에 JSON으로 저장되지 않는다는 점을 알고 있어야 합니다. 마지막 예의 주소 필드와 같이 중첩된 개체를 인덱싱하면 Elasticsearch는 개체를 평면화하여 다음과 같이 만듭니다.
{
"name": "Lucas",
"birthday": "1990-09-28",
"address.country": "Brazil",
"address.zipCode": "04896060"
}
대신 주소 배열이 있다면 어떨까요? 이 경우 Elasticsearch는 국가 배열 및 zipCode 배열과 같은 필드를 저장하므로 다음과 같습니다.
POST /articles/_doc
{
"name": "Elasticsearch article",
"reviews": [
{
"name": "Lucas",
"rating": 5
},
{
"name": "Eduardo",
"rating": 3
}
]
}
다음과 같이 저장됩니다.
{
"name": "Elasticsearch article",
"reviews.name": ["Lucas", "Eduardo"],
"reviews.rating": [5, 3]
}
중첩 데이터 유형
이전 예에서 우리는 2명의 다른 사용자가 작성한 2개의 리뷰가 포함된 기사를 나타내는 문서를 인덱싱했습니다. 다음 쿼리를 실행하여 Eduardo가 검토한 4보다 큰 등급의 기사를 가져오도록 합시다.
GET /articles/_search
{
"query": {
"bool": {
"must": [
{"match": { "reviews.name": "Eduardo" }},
{"range": { "reviews.rating": {"gt": 4} }}
]
}
}
}
다음과 같은 결과를 얻게 됩니다.
...
"hits" : [
{
"_index" : "articles",
"_id" : "sboYZIEBFSkh39rxJql6",
"_score" : 1.287682,
"_source" : {
"name" : "Elasticsearch article",
"reviews" : [
{
"name" : "Lucas",
"rating" : 5
},
{
"name" : "Eduardo",
"rating" : 3
}
]
}
}
]
...
이것은 정확히 우리가 찾고 있는 것이 아니며 그 이유는 무엇입니까? 기본적으로 Elasticsearch는 문서를 평면화했기 때문에 관련이 없기 때문에 이러한 필터를 기반으로 쿼리할 수 없습니다. 하지만 이런 관계가 필요하다면 어떨까요? 여기에서 데이터 유형
nested
이 사용됩니다.이 데이터 유형은 기본적으로 Elasticsearch에 중첩 객체가 상위 객체와 관계가 있음을 알려줍니다. 같은 예를 보되
reviews
필드를 nested
로 정의합니다.PUT /articles_v2
{
"mappings": {
"properties": {
"name": {"type": "text"},
"reviews": {"type": "nested"}
}
}
}
이전과 동일한 문서를 색인화해 보겠습니다.
POST /articles_v2/_doc
{
"name": "Elasticsearch article",
"reviews": [
{
"name": "Lucas",
"rating": 5
},
{
"name": "Eduardo",
"rating": 3
}
]
}
이제 등급이 4보다 큰 Eduardo가 검토한 기사를 검색하는 중첩 쿼리를 만들어 보겠습니다.
GET /articles_nested_v2/_search
{
"query": {
"nested": {
"path": "reviews",
"query": {
"bool": {
"must": [
{ "match": {"reviews.name": "Eduardo"} },
{ "range": {"reviews.rating": {"gt": 4}} }
]
}
}
}
}
}
반환 결과에는 이러한 조건과 일치하는 기사가 없는 것으로 표시됩니다. 이는 정확합니다!
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
Reference
이 문제에 관하여(Elasticsearch: 객체 및 중첩 데이터 유형), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/rivelles/elasticsearch-object-and-nested-data-types-11oe텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)