Elasticsearch 연관 관계 - 중첩

13301 단어

중첩 - 객체


내포된 객체


사실, Elasticsearch에서 창설주 삭제주 수정 문서는 원자적이기 때문에 우리는 한 문서에 밀접한 관련 실체를 저장할 수 있다.예를 들어 우리는 한 문서에 주문서와 그 모든 내용을 저장하거나 Blog 글과 그 모든 응답을 저장하여comments 진열을 전달할 수 있다.
PUT /my_index/blogpost/1 { "title": "Nest eggs", "body": "Making your money work...", "tags":  [ "cash", "shares" ], "comments": [ <1> { "name": "John Smith", "comment": "Great article", "age": 28, "stars": 4, "date": "2014-09-01" }, { "name": "Alice White", "comment": "More like this please", "age": 31, "stars": 5, "date": "2014-10-22" } ] } 

<1> 동적 맵에 의존하면comments 칸은 자동으로 Object 칸으로 만들어집니다.
모든 내용이 같은 문서에 있기 때문에 검색할 때 블로그 글과 응답을 연결할 필요가 없기 때문에 검색이 더욱 우수하다.
문제는 위의 문서에서 다음과 같은 검색과 일치할 수 있습니다.
GET /_search
{ "query": { "bool": { "must": [
        { "match": { "name": "Alice" }},
        { "match": { "age": 28 }} <1>
      ]
    }
  }
}

<1> 앨리스는 31살이지 28살이 아니다!
객체 배열에서 설명한 것처럼 객체 간 쌍이 만들어지는 이유는 아름다운 구조의 JSON 문서가 색인에서 아래쪽 키-값 형식으로 편평하게 만들어졌기 때문입니다.
{ "title":            [ eggs, nest ], "body":             [ making, money, work, your ], "tags":             [ cash, shares ], "comments.name":    [ alice, john, smith, white ], "comments.comment": [ article, great, like, more, please, this ], "comments.age":     [ 28, 31 ], "comments.stars":   [ 4, 5 ], "comments.date":    [ 2014-09-01, 2014-10-22 ]
}

Alice와 31, John과 2014-09-01 사이의 관계는 이미 돌이킬 수 없이 사라졌다.Object 형식의 칸은 단일 대상을 저장하는 데 매우 유용합니다.검색의 측면에서 볼 때, 하나의 대상 진열을 정렬하는 데 있어서 관련은 필요 없는 것이다.
이것은 끼워 넣는 대상이 설계되어 해결되는 문제다.commments 막대를 Object 유형 대신 nested 형식으로 매핑하면 중첩된 각 객체는 숨겨진 분할 문서로 인덱스됩니다. 예를 들어,
{ <1> "comments.name": [ john, smith ], "comments.comment": [ article, great ], "comments.age": [ 28 ], "comments.stars": [ 4 ], "comments.date": [ 2014-09-01 ] } { <2> "comments.name": [ alice, white ], "comments.comment": [ like, more, please, this ], "comments.age": [ 31 ], "comments.stars": [ 5 ], "comments.date": [ 2014-10-22 ] } { <3> "title": [ eggs, nest ], "body": [ making, money, work, your ], "tags": [ cash, shares ] } 

<1> 첫 번째 중첩 객체
<2> 두 번째 네스트된 객체
<3> 루트 또는 상위 문서
각각의 끼워 넣은 대상을 색인함으로써 대상의 칸에서 연결을 유지합니다.우리의 조회는 같은 플러그인 대상이 일치할 때만 응답할 수 있습니다.
뿐만 아니라 중첩된 객체가 인덱스되므로 중첩된 객체를 루트 문서로 연결하는 질의가 거의 단일 문서를 질의하는 것과 같이 빠릅니다.
이러한 추가 중첩 객체는 숨겨져서 직접 액세스할 수 없습니다.주 수정을 추가하거나 플러그인 대상을 제거하기 위해서, 우리는 전체 문서를 다시 인덱스해야 합니다.검색 요구 사항의 결과는 중첩된 객체만 있는 것이 아니라 전체 문서임을 명심하십시오.

네스트-매핑


네스트된 객체 매핑


nested 표시줄을 설정하는 것은 간단합니다. Object 형식으로 설정할 수 있는 곳에서 nested 형식으로 변경합니다.
PUT /my_index
{ "mappings": { "blogpost": { "properties": { "comments": { "type": "nested", <1> "properties": { "name": { "type": "string" }, "comment": { "type": "string" }, "age": { "type": "short" }, "stars": { "type": "short" }, "date": { "type": "date" } } } } } } } 

< 1 > nested 표시줄에서 Object 형식과 같은 인자를 받아들입니다.
필요한 건 그뿐이야.모든comments 대상은 분리 플러그인 대상으로 인덱스됩니다.더 많은 nested type reference docs를 참조하십시오.

중첩 - 질의


네스트된 객체 질의


네스트된 객체 (nested objects) 는 분리된 숨겨진 문서로 인덱스되기 때문에 직접 조회할 수 없습니다.대신 nested 쿼리 또는 nested 필터를 사용하여 액세스합니다.
GET /my_index/blogpost/_search
{ "query": { "bool": { "must": [
        { "match": { "title": "eggs" }}, <1> { "nested": { "path": "comments", <2> "query": { "bool": { "must": [ <3> { "match": { "comments.name": "john" }}, { "match": { "comments.age": 28 }} ] }}}} ] }}} 

<1> title 조건은 루트 문서에서 작동합니다
<2> nested 조건은 삽입된comments 슬롯에 깊이 들어갑니다.이것은 루트 문서를 저장하는 칸이나 다른 끼워 넣은 문서의 칸에 있지 않습니다.
<3> comments.name 및comments.age는 같은 플러그인 문서에서 작동합니다.

TIP


하나의 nested 칸은 다른 nested 칸을 포함할 수 있습니다.같은, 하나의 nested 조회는 다른 nested 조회를 포함할 수 있습니다.플러그인 계층은 네가 예상한 대로 작동할 것이다.
물론,nested 조회는 여러 개의 끼워 넣은 문서와 일치할 수 있습니다.각 문서의 일치에는 관련 점수가 있지만 루트 문서에 적용하려면 여러 점수를 단일 점수로 줄여야 합니다.
사전 설정에서 중첩된 모든 문서가 일치하는 평균 점수를 받습니다.이것은 score를 설정해서mode 매개 변수는 avg, max,sum 또는 심지어 none (루트 문서가 1.0의 일치 점수를 영원히 얻지 못하도록 방지하기 위해서) 이다.
GET /my_index/blogpost/_search
{ "query": { "bool": { "must": [
        { "match": { "title": "eggs" }},
        { "nested": { "path": "comments", "score_mode": "max", <1> "query": { "bool": { "must": [ { "match": { "comments.name": "john" }}, { "match": { "comments.age": 28 }} ] }}}} ] }}} 

<1> 가장 일치하는 중첩 문서에서 루트 문서를 주는score 값.

주의


nested 필터는 nested 검색과 유사합니다. score 를 사용할 수 없습니다.mode 매개 변수.Filter context - 예를 들어 Filtered 쿼리에서만 사용할 수 있습니다. 다른 필터와 유사합니다. 포함하거나 포함하지 않지만 점수를 매기지 않습니다.
nested 필터의 결과 자체는 캐시되지 않습니다. 보통 캐시 규칙은 nested 필터에 적용됩니다.

네스트된 정렬


네스트된 막대로 정렬


우리는 플러그인 칸의 값에 따라 정렬할 수 있으며, 심지어는 플러그인 문서의 값을 분리할 수도 있다.그 결과를 더욱 흥미롭게 하기 위해 우리는 또 다른 기록을 추가했다.
PUT /my_index/blogpost/2 { "title": "Investment secrets", "body": "What they don't tell you ...", "tags":  [ "shares", "equities" ], "comments": [
    { "name": "Mary Brown", "comment": "Lies, lies, lies", "age": 42, "stars": 1, "date": "2014-10-18" },
    { "name": "John Smith", "comment": "You're making it up!", "age": 28, "stars": 2, "date": "2014-10-16" }
  ]
}

10월에 응답을 받은 블로그 글을 되찾고, 되찾은 블로그 글 중 가장 적은 stars 수량의 순서에 따라 정렬해야 한다고 상상하십시오.이 검색 요청은 다음과 같습니다.
GET /_search
{ "query": { "nested": { <1> "path": "comments", "filter": { "range": { "comments.date": { "gte": "2014-10-01", "lt": "2014-11-01" } } } } }, "sort": { "comments.stars": { <2> "order": "asc", <2> "mode": "min", <2> "nested_filter": { <3> "range": { "comments.date": { "gte": "2014-10-01", "lt": "2014-11-01" } } } } } } 

<1> nested 검색은 10월에 응답을 받은 블로그 글을 제한합니다.
<2> 결과는 모든 일치하는 응답에 따라comment.stars 표시줄의 최소값 (min) 을 증가 (asc) 로 정렬합니다.
<3> 정렬 조건의 nestedfilter는 주 검색query 조건의nested 검색과 같습니다.다음 설명은
왜 우리가 nestedFilter에서 검색 조건을 반복해서 쓰시겠습니까?검색을 실행한 후에야 정렬이 발생했기 때문이다.이 검색은 10월에 응답을 받은 블로그 글과 일치하며, 블로그 문서를 결과로 되돌려줍니다.하면, 만약, 만약...Filter 조건, 우리는 마지막으로 10월에 받은 것이 아니라 블로그에서 받은 모든 응답에 따라 정렬할 것입니다.

네스트-컬렉션


네스트-컬렉션


우리가 조회할 때nested 조회를 사용하여 끼워 넣은 대상을 저장해야 하는 것과 같이 전문적인nested 집합은 끼워 넣은 대상의 난간 집합을 얻을 수 있습니다.
GET /my_index/blogpost/_search?search_type=count
{ "aggs": { "comments": { <1> "nested": { "path": "comments" }, "aggs": { "by_month": { "date_histogram": { <2> "field": "comments.date", "interval": "month", "format": "yyyy-MM" }, "aggs": { "avg_stars": { "avg": { <3> "field": "comments.stars" } } } } } } } } 

<1> nested 집합 삽입 대상의comments 슬롯 깊이
<2> 논평은comments에 기초한다.date 표시줄이 월별로 나누어집니다
<3> 월별 세그먼트당 별표 평균 계산
결과 집합은 중첩된 문서 수준에서 발생합니다.
... "aggregations": { "comments": { "doc_count": 4, <1> "by_month": { "buckets": [ { "key_as_string": "2014-09", "key": 1409529600000, "doc_count": 1, <1> "avg_stars": { "value": 4 } }, { "key_as_string": "2014-10", "key": 1412121600000, "doc_count": 3, <1> "avg_stars": { "value": 2.6666666666666665 } } ] } } } ... 

<1>여기 총 4개의comments:하나는 9월 및 셋은 10월

대칭 이동-네스트-컬렉션


네스트-컬렉션 대칭 이동


하나의 nested 집합은 끼워 넣은 문서의 칸만 저장할 수 있고, 루트 문서나 다른 끼워 넣은 문서의 칸은 볼 수 없습니다.그러나, 우리는 플러그인 블록을 뛰어넘어reversenested 집합은 부층으로 돌아간다.
예를 들어 평론가의 나이에 태그를 붙이는 것이 재미있다는 것을 알 수 있다. comment.age는 중첩 표시줄에 있지만 tags는 루트 문서에 있습니다:
GET /my_index/blogpost/_search?search_type=count
{ "aggs": { "comments": { "nested": { <1> "path": "comments" }, "aggs": { "age_group": { "histogram": { <2> "field": "comments.age", "interval": 10 }, "aggs": { "blogposts": { "reverse_nested": {}, <3> "aggs": { "tags": { "terms": { <4> "field": "tags" } } } } } } } } } } 

<1> nested 집합comments 대상 깊이 들어가기
<2> histogram 집합은comments.age 칸은 10년마다 하나씩 모인다
<3> reverse_nested 집합이 루트 문서로 되돌아오기
<4>terms 집합은 각 연령대의 붉은 단어를 계산한다
간략한 결과는 다음과 같습니다.
.. "aggregations": { "comments": { "doc_count": 4, <1> "age_group": { "buckets": [ { "key": 20, <2> "doc_count": 2, <2> "blogposts": { "doc_count": 2, <3> "tags": { "doc_count_error_upper_bound": 0, "buckets": [ <4> { "key": "shares", "doc_count": 2 }, { "key": "cash", "doc_count": 1 }, { "key": "equities", "doc_count": 1 } ] } } }, ... 

<1> 총 4개의 의견
<2> 두 개의 평론가가 20~30사이에 있다
<3> 두 블로그 글은 이 댓글과 관련이 있다
<4> 이 블로그 글의 붉은 라벨은shares주cash주equities

언제 플러그인 대상을 사용해야 합니까


플러그인 대상은 주요 실체(예를 들어blogpost)에 유한한 수량의 밀접한 관련 실체(예를 들어comments)를 더하는 데 매우 유용하다.평론 내용으로 블로그 글을 찾을 수 있는 방법이 매우 유용하고, nested 조회 및 필터는 짧은 조회 시간 연결 (fast query-time joins) 을 제공합니다.
네스트된 모델의 단점은 다음과 같습니다.
4
  • 주 수정을 추가하거나 삽입된 문서를 삭제하려면 전체 문서를 다시 인덱스해야 합니다.따라서 중첩된 문서가 많을수록 비용이 많이 든다

  • 4
  • 일치하는 중첩된 문서만 있는 것이 아니라 전체 문서를 되돌려 달라는 요청을 검색합니다.루트 문서와 가장 일치하는 플러그인 문서만 전송할 계획이 있지만, 현재는 지원되지 않습니다

  • 때때로 당신은 주요 문서와 관련된 실체를 완전하게 분리해야 한다.부모-자식 관계가 이 기능을 제공합니다.

    좋은 웹페이지 즐겨찾기