공간 바티칸

데이터의 색인을 생성 할 때,세계는 거의 고립에 존재하는 각 문서만큼 간단하지 않습니다. 때로는 모든 데이터를 하위 문서로 비정규 화하는 것이 좋습니다. 예를 들어 책을 모델링하는 경우 신뢰할 수 있는 데이터 소스인 데이터베이스에서 데이터가 별도의authorsbooks테이블로 분할되는 경우에도 책에 저자 필드를 추가하는 것이 좋습니다. 그것은 간단하고 당신은 쉽게 책의 속성과 저자의 이름 모두에 대한 쿼리를 구성 할 수 있습니다.

항상 실용적이지는 않습니다-부모 문서에 너무 많은 데이터가 있어 각 자식 문서에 복제할 수 있습니다. 당신이 당신의 전형적인 블로그/코멘트 응용 프로그램이 있다면 당신은이 크게 인덱스 데이터 몇 가지의 양을 늘릴 것 같은 각 코멘트에 블로그 게시물의 전체 내용을 반복하고 싶지 않을 것입니다. 그러나 그 없이는 특정 기준과 일치하는 게시물에 대한 주석을 찾기 위해 쿼리를 쉽게 작성할 수 없습니다(일치하는 게시물을 먼저 찾은 다음 특정post_id으로 주석을 가져 오는 프로세스의 2 단계를 수행하는 것 외에는 종종 다루기 힘들거나 느립니다(또는 둘 다)).

또 다른 옵션은 부모 문서 안에 자식 문서를 배치하는 것입니다.

123456789101112
{ "name": "A. N Author", "biography": "A leading wordsmith", "books": }

여기서 한 가지 단점은 자식을 추가하면 전체 문서를 다시 인덱싱해야한다는 것입니다. 특정 장르의 책을 쓴 작가를 찾는 것은 쉽지만 펭귄이 출판 한 공상 과학 책을 가진 작가를 찾는 것은 어렵습니다.

인덱스에

이 포함되어 있으면 가장 확실한 쿼리

이 두 저자를 모두 찾습니다.publishedgenre에 대한 조건이 같은 책과 일치해야한다고 표현할 수 없습니다.

엘라스틱서치는 이에 도움이 되는 두 가지를 제공합니다. 첫 번째는 중첩 된 문서/쿼리의 개념입니다. 이것은 너가 적어도 1 권의 책이 너의 표준의 양쪽을 만족시키는 곳에 너가 저자를 찾고 있는 것과 말하는 허용한다.

먼저 책 필드가 중첩될 것이라고 말하는 매핑을 설정해야 합니다:

123456789
curl -XPOST localhost:9200/authors/nested_author/_mapping -d '{ "nested_author":{ "properties":{ "books": { "type": "nested" } } }}'

이 새 인덱스에 이전과 동일한 데이터를 삽입하면이 쿼리

여기서nested필터를 사용하면 중첩 된 문서(즉,책)에 대해 쿼리를 실행하고 쿼리와 일치하는 중첩 된 문서가 하나 이상인 작성자를 필터링 할 수 있습니다. path옵션은 작성자 문서의 어느 부분에 이 쿼리가 적용되는지 알려주고query옵션은 이러한 중첩된 문서에 대해 실행할 쿼리입니다. 이전 쿼리와 달리 이 두 가지 요구 사항을 모두 충족하는 개별 책을 찾을 수 있어야 합니다. 이전 예제는 작성자를 상위 문서로,책을 하위 문서로 재작업할 수 있습니다.

이번에는 책과 별도로 저자를 색인화 한 다음 책 유형에 대한 매핑을 구성하고 상위 유형이bare_author라고 말합니다. 당신은 당신이 어떤 책을 창조하기 전에 이것을 할 필요가 있다.

12345
curl -XPOST localhost:9200/authors/book/_mapping -d '{ "book":{ "_parent": {"type": "bare_author"} }}'

우리는 책을 색인을 생성 할 때,당신은 다음 부모의 아이디를 제공해야합니다(즉,우리는 이전에 만든 저자 중 하나의 아이디를 제공)

탄성 검색은 주석에 말하는 것을 거의 수행하는has_child필터를 제공합니다: 특정 쿼리를 만족하는 자식이 하나 이상인 상위 문서를 선택합니다. 이 쿼리는 알라 레이놀즈 만 찾습니다:

솔 4.0 분명히 조인을 할 수있는 능력이있을 것이다,지금까지 내가 말할 수 있지만이 몇 가지 제한과 함께 제공,특히 더 조인 당신이 분산 환경에서 작동하는 경우. 자식은 항상 부모와 동일한 샤드에서 인덱싱되므로has_child은 어색한 교차 샤드 작업을 수행 할 필요가 없습니다.

목록 작성

공유 전역 항목의 사용자별 목록을 모델링하는 데도 사용할 수 있습니다(예:사용자가 평가한 항목을 원하는 경우). 이 경우 자식 문서는 특정 사용자가 특정 게시물을 평가했다는 사실을 나타냅니다.이 문서는user_id,post_id및 등급:관계형 데이터베이스 용어의 조인 테이블에 지나지 않습니다.

부모/자식 관계를 사용하여has_child사용자가 게시물 내용,날짜 또는 게시물의 속성 또는 하위 항목 속성 중 하나를 기반으로 자신의 즐겨 찾기를 통해 검색 할 수 있도록하면서 사용자가 즐겨 찾는 모든 게시물을 쉽게 찾을 수 있습니다. 매우 작은rating항목만 인덱싱하면 됩니다.

이 문서

이 쿼리

은 볼리비아가 관심 있는 사용자가 3 을 초과하여 평가한 유일한 게시물이기 때문에”볼리비아 등급 4″만 찾습니다. 제목에 대한 최상위 쿼리는 게시물에 적용되며,여기서has_child필터 내부의 쿼리는 자식이 일치해야 하는 조건을 설명합니다(이 경우 특정 사용자에 속하고 특정 등급이 있어야 함).

주문

has_child이 허용하지 않는 것은 자식의 속성 또는 자식의 반환 속성을 기반으로 주문하는 것입니다. 당신은 그들이 평가 된 경우에 따라 또는 평가를 감소하여 사용자의 평가 게시물을 주문하고 싶다면 당신은 직접 게시물/평가에 대해 검색 할 수 있지만,당신은 너무 게시물에 일부 검색 크리테라를 적용 할 수 있습니다. 예를 들어 특정 주제에 대한 평가 게시물 만 찾을 수 있습니다(사용자가 준 등급에 따라 계속 주문). has_child을 사용하면 운이 없습니다. 중첩 된 문서도 도움이되지 않습니다.

0.19.10 현재has_parent필터를 사용할 수 있습니다. 이 기능은 자식이 있는 것과 거의 동일하게 작동하지만 대신 상위 항목에 대한 쿼리를 지정할 수 있습니다. 이 쿼리는 제목이”볼리비아”와 일치하는 게시물에 대해 사용자 1234 별 등급을 반환하고 점수 순서가

감소하면 등급 개체가 반환됩니다.

가짜

이전 버전의 엘라스틱 검색에 갇혀 있다면top_children를 사용하여 대부분의 방법을 얻을 수 있습니다. 설명서에서 말한 것처럼top_children는 먼저 자식 문서를 쿼리 한 다음 부모 문서로 집계합니다. 이 예제에서는 탄성 검색에서 먼저 쿼리와 일치하는 등급 문서를 찾을 수 있음을 의미합니다. 그런 다음 각 등급을 상위 게시물에 일치시켜 존재하는 중복 게시물을 집계합니다.

맨 위 자식이 있는 가로장 설치 같은 비트는 탄성 검색이 집계가 발생할 때 얼마나 많은 문서가 손실되는지 미리 알지 못한다는 것입니다. 이 특별한 경우에는 동일한 사용자에 의한 두 개의 별개 등급이 항상 두 개의 별개 게시물에 해당하므로 집계 단계가 아무 것도하지 않기 때문에factorincremental_factor설정을 귀찮게 할 필요가 없습니다. 마찬가지로 점수 모드도 중요하지 않습니다. 전체 결과 수의 정확한 개수를 제공해야 하는 경우factor을 자식 문서의 첫 번째 스윕 탄성 검색에서 모두 찾을 수 있을 만큼 크게 설정하기만 하면 됩니다. 사용자가 목록에 500 개의 등급 항목을 가지고 있고 처음 10 개의 항목을 요구한다는 것을 알고 있다면 50 의 요소가 트릭을 수행해야합니다. 사용자가 특정 등급의 하위 집합을 검색하는 경우 별도의 탄력적 검색 쿼리없이 해결하기가 어려울 수 있습니다.

이 모든 후에 얻는 것은 하위 문서(등급)의 쿼리 점수별로 정렬 된 상위 문서(게시물)목록입니다. 자식 문서의 속성에 따라 게시물을 정렬의 원래 목표를 달성하기 위해 우리는이 쿼리 점수가 올바른 값을 가지고 있는지 확인해야합니다. 예를 들어top_children쿼리가custom_score쿼리를 래핑하여 각 자녀의 점수를 제어할 수 있도록 합니다.

색인에 동일한 문서가 있는 경우 이 쿼리는 사용자 1234 가 평가한 게시물을 해당 등급별로 정렬하여 반환합니다:

우리는top_children쿼리를 실행하고 있으므로 가장 먼저해야 할 일은 우리가 고려중인 어린이의 유형(등급)을 말하는 것입니다. 그런 다음 우리는 그 아이들을 찾는 쿼리를 제공합니다. 이 쿼리는custom_score쿼리이며filtered쿼리를 래핑합니다. filtered쿼리를 사용하면 관심 있는 사용자가 지정한 등급만 찾은 다음script요소를 사용하면 등급 문서의 점수가 자체 등급으로 지정되어 게시물을 등급별로 정렬할 수 있습니다. 백슬래시를 사용한 재미는 작은 따옴표로 구분 된 쉘 친화적 인 문자열에 리터럴 작은 따옴표를 포함하려고하기 때문입니다.

루비 재미

불행하게도 타이어 라이브러리는 정말 지금이 재미있는 물건 중 하나를 지원하지 않습니다-순간에 모든 하나의 작은 쿼리 유형과 옵션이 타이어 전체에 흩어져 별도의 방법이 될 끝 때문에 추가되는 이러한 종류의 기능에 대한 모라토리엄의 비트가있다,이는 메인테이너는 당연히 좋아하지 않는다. 당신은 일종의 그것을 해킹 할 수 있습니다.

타이어는 색인 생성 시 문서의 부모 아이디를 설정할 수 없습니다. 이것은 추가 간단 하 고 앞서 언급 한 모라토리엄에 의해 개최 되 고. 내 포크는이 기능을 추가합니다. 결국

의 불행은 타이어의 자동 인덱스 생성은 인덱스 당 하나의 유형을 가정하지만 부모/자식 관계가 존재하려면 두 유형이 동일한 인덱스에 있어야 한다는 것입니다. 나는 내 인덱스를 만들기 위해 이와 같은 일을 끝냈다.

꽤 아름답지는 않지만 일을 끝냅니다.

마지막으로 실제로 쿼리를 수행해야합니다. 그래서

이 약간의 불쾌감은 쿼리를 해시로 빌드 한 다음 다른 방법으로 보는 동안 타이어에 밀어 넣습니다. 분명히 당신은 검색에 다른 조건(게시물 또는 평가 여부)을 쉽게 추가 할 수있는 방식으로 구성 할 수 있습니다. (타이어 기여의 로거 확장과 충돌 페이로드 옵션 버그가있다)

답글 남기기

이메일 주소는 공개되지 않습니다.