object의 동작방식
elasticsearch는 내부 객체의 개념이 없다. 그래서 객체 구조를 단순 키/값 형태로 표시한다.
PUT index-object/\_doc/1
{
"group" : "fans",
"user" : \[
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
\]
}
위의 user 필드는 object 필드로 추가된다.
그리고 이 문서는 내부적으로 아래와 같이 변환될 것이다.
{
"group" : "fans",
"user.first" : \[ "alice", "john" \],
"user.last" : \[ "smith", "white" \]
}
user.first와 user.last 필드는 multi-value로 변환되고 alice와 white와의 연관성을 없어진다. 이 문서는 alice와 smith에 대한 쿼리를 부정확하게 조회할 것이다.
GET index-object/\_search
{
"query": {
"bool": {
"must": \[
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "Smith" }}
\]
}
}
}
nested 필드 사용하기
만일 객체 배열이 필요하고 배열에서 서로 독립성을 유지하고 싶다면 `object` 타입 대신 `nested` 타입을 사용하자.
내부적으로 nested object는 별개의 숨겨진 문서로 각각 인덱스하며 각 nested object는 서로 무관하게 조회된다.
PUT index-nested
{
"mappings": {
"properties": {
"user": {
"type": "nested"
}
}
}
}
PUT index-nested/\_doc/1
{
"group" : "fans",
"user" : \[
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
\]
}
# 이 쿼리는 검색이 되지 않는다.
GET index-nested/\_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": \[
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "Smith" }}
\]
}
}
}
}
}
# 검색하려면 아래와 같이 사용한다.
GET index-nested/\_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": \[
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "White" }}
\]
}
},
"inner\_hits": {
"highlight": {
"fields": {
"user.first": {}
}
}
}
}
}
}
nested 필드 파라미터
dynamic
(optional, string) 새로운 properties가 기존 nested 객체에 동적으로 추가될수 있는지 여부. true(기본값), false, strict
properties
(optional, object) nested object 내의 필드, nested를 포함해 어떤 데이터 유형도 될 수 있다. 새로운 properties가 기존 nested object에 추가될 수 있다.
include_in_parent
(optional, boolean) true라면 nested object의 모든 필드가 flat하게 상위 문서에 추가된다. 기본값은 false
include_in_root
(optional, boolean) true라면 nested object의 모든 필드가 root 문서에 추가된다. 기본값은 false
nested 매핑과 object의 제약사항
각 nested object는 별도 루씬 문서로 인덱싱된다.
만일 100개의 user 객체를 가지는 단일 문서를 인덱싱한다면 101개의 루씬 문서가 생성된다: 부모 문서용과 각 nested object용. nested mapping의 비용이 비싼 연결작업 때문에, elasticsearch는 성능문제를 위한 설정을 두고 있다.
index.mapping.nested_fields.limit
고유한 nested mapping의 최대 수. 기본값은 50
index.mapping.nested_objects.limit
단일 문서가 nested type을 가질 수 있는 nested JSON 객체의 최대 수. 기본값은 10000
참고: https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html