'Elastic Search/01. Getting Started'에 해당되는 글 21건
- 2015/04/23 용비 21. Conclusion
- 2015/04/23 용비 20. Exploring Your Data - Executing Aggregations
- 2015/04/22 용비 19. Exploring Your Data - Executing Filters
- 2015/04/22 용비 18. Exploring Your Data - Executing Searches
- 2015/04/22 용비 17. Exploring Your Data - Introducing the Query Language
20. Exploring Your Data - Executing Aggregations
Elastic Search/01. Getting Started 2015/04/23 13:24[Executing Aggregations]
Aggregations는 데이터를 group하고 통계를 추출하는 기능을 제공한다. Aggregation에 대해서는 SQL GROUP BY와 SQL aggregate function과 거의 같다고 생각하는 것이 가장 쉽다. Elasticsearch에서는 하나의 response 안에 hit를 리턴하는 검색과 hit별로 분리된 aggregated result를 동시에 실행하는 기능이 있다. 이것은 굉장히 강력하고 효율적인 기능이다. 여러분은 query와 multiple aggregation을 실행하여 간결하고 간단한 API를 통해서 네트워크의 빈번한 호출을 피하고, 한번에 두개 혹은 하나의 결과를 받아볼 수 있다.
다음 에제는 상태별로 모든 account를 group하고, count 내림차순 정렬된 결과 중에서 top 10개의 state를 리턴하는 것을 보여준다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"size": 0,
"aggs": {
"group_by_state":
{
"terms": {
"field":
"state"
}
}
}
}'
SQL에서는 위의 aggregation 예제는 다음 개념과 유사하다.
SELECT COUNT(*) from bank GROUP BY state ORDER BY COUNT(*) DESC
응답 결과의 부분적인 내용은 다음과 같다.
"hits" : {
"total" : 1000,
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
"group_by_state" : {
"buckets" : [ {
"key" : "al",
"doc_count" : 21
}, {
"key" : "tx",
"doc_count" : 17
}, {
"key" : "id",
"doc_count" : 15
}, {
"key" : "ma",
"doc_count" : 15
}, {
"key" : "md",
"doc_count" : 15
}, {
"key" : "pa",
"doc_count" : 15
}, {
"key" : "dc",
"doc_count" : 14
}, {
"key" : "me",
"doc_count" : 14
}, {
"key" : "mo",
"doc_count" : 14
}, {
"key" : "nd",
"doc_count" : 14
} ]
}
}
}
위에서 AL(abama)에 21개의 account, 그 다음으로 TX에 17개의 account, ID에 15개 등등이 있음을 알 수 있다. size=0으로 설정하면 response에서 aggregation 결과만 보고 싶은 경우이기 때문에 search hit을 보여주지 않는다.
다음 예제는 state별로 account balance의 평균을 계산하는 것을 보여준다.
(역시, 내림차순 정렬하여 top 10개만 출력한다.)
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"size": 0,
"aggs": {
"group_by_state":
{
"terms": {
"field":
"state"
},
"aggs": {
"average_balance":
{
"avg": {
"field":
"balance"
}
}
}
}
}
}'
어떻게 group_by_state aggregation내에 average_balance aggregation을 연결했는지 주목하라. 모든 aggregation은 이와 같은 공통된 pattern을 가지고 있다. 여러분이 데이터로부터 구하고자 하는 독자적인 요약 정보를 추출하는 aggregation내에 연결된 aggregation을 가질 수 있다. 앞에서 수행한 aggregation에서 내림차순으로 average balance를 정렬해 보자.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"size": 0,
"aggs": {
"group_by_state":
{
"terms": {
"field":
"state",
"order": {
"average_balance":
"desc"
}
},
"aggs": {
"average_balance":
{
"avg": {
"field":
"balance"
}
}
}
}
}
}'
다음 예제는 어떻게 우리가 연령대별로, 성별에 따라 group할 수 있는지, 마지막으로 어떻게 연령대별, 성별에 따른 average account balance를 구할 수 있는지를 보여준다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"size": 0,
"aggs": {
"group_by_age":
{
"range": {
"field":
"age",
"ranges": [
{
"from":
20,
"to": 30
},
{
"from":
30,
"to": 40
},
{
"from":
40,
"to": 50
}
]
},
"aggs": {
"group_by_gender": {
"terms": {
"field":
"gender"
},
"aggs": {
"average_balance":
{
"avg": {
"field":
"balance"
}
}
}
}
}
}
}
}'
여기에서 우리가 상세히 다루지 않은 다른 많은 aggregation 기능이 있다. Aggregation reference guide (http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html) 를 통해서 더 많은 내용을 알 수 있다.
[Executing Filters]
앞 섹션에서 document score (검색 결과의 _score 필드)에 대해서는 자세히 다루지 않고 넘어 갔었다. Score는 우리가 검색하고자 한 query와 document가 얼마나 match하는지를 측정한 숫자 값이다. Score가 높을수록 더 적합한 document이고, Score가 낮을수록 덜 적합한 document이다.
Elasticsearch의 모든 query는 적합성 score (점수)의 계산을 수행한다. 적합성 점수 (relevance score)가 불필요한 경우에 Elasticsearch는 query-dsl-filter, filter 형태의 또 다른 기능을 제공한다. Filter는 2가지 중요한 이유 때문에, 개념적으로 query를 더 빠르게 수행하도록 최적화 하는 것과 같다.
- Filter는 score 계산을 하지 않기 때문에 query보다 빠르다.
- Filter는 반복되는 검색 결과를 memory에 cache할 수 있기 때문에 query보다 빠르다.
Filter를 이해하기 위해서는, query와 filter를 조합한 filtered Query (http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-filtered-query.html) 에 대해서 먼저 아는 것이 좋다.
예를 들어, range filter를 소개하자면, 값의 range에 따라 document를 filter할 수 있다. 일반적으로 숫자나 날짜별로 filter를 적용하여 사용한다.
다음 예제는 20000과 30000 사이의 balance를 가지는 모든 account를 리턴하는 filtered query를 사용한 것이다. 다른 말로 하자면, 20000 이상 30000 이하의 balance를 가진 account를 찾고 싶은 것이다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"filtered": {
"query": {
"match_all": {} },
"filter": {
"range": {
"balance":
{
"gte":
20000,
"lte":
30000
}
}
}
}
}
}'
위 내용을 분석해 보면, filtered query는 query part인 match_all query와 filter part인 range filter를 포함하고 있다. 다른 query로 query part를 대체할 수 있고, 다른 filter로 filter part를 대체할 수 있다. 위의 경우에 range filter는 모든 document들이 range안에 동일하게 들어오기 때문에 완벽하다. 즉, 모든 document가 동일하다.
일반적으로 어떤 filter나 query를 원하는지 결정하는 가장 쉬운 방법은 relevance score (적합성 점수)를 신경 쓰는지 스스로에게 물어보는 것이다. Relevance score (적합성 점수)가 중요하지 않다면 filter를 사용하고, 중요하다면 query를 사용하라. SQL 배경지식이 있다면, query와 filter는 SELECT WHERE 절 개념과 유사하다. 비록 filter가 query보다 조금 더 유사하지만.
게다가, match_all, match, bool, filtered, range query 이외에도 다른 많은 이용할 수 있는 query/filter들이 있다. 여기서는 깊이 다루지 않을 것이다. 어떻게 동작하는지에 대한 기본적인 이해를 하고 있기 때문에, 다른 query/filter를 배우고 시험하면서 이런 지식을 활용하는데 어렵지는 않을 것이다.
[Executing Searches]
지금까지 우리는 몇 가지 기본적인 검색 파라미터들을 살펴보았다. 이제 Query DSL에 대해서 좀 더 깊이 파고 들어가 보자. 첫번째로 리턴되는 document 필드들을 살펴보자. 기본적으로 전체 JSON document는 모든 검색의 일부로 리턴된다. 이것은 source (검색 결과에서 _source 필드에 해당함)를 참조한다. 만약 전체 source document의 리턴을 원치 않으면 리턴되는 source내의 몇가지 필드만 요청할 수도 있다.
다음 예제는 _source내의 2가지 필드 - account_number, balance - 만을 검색으로부터 어떻게 리턴 받는지를 보여준다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"match_all": {} },
"_source":
["account_number", "balance"]
}'
위의 예제에서 간단하게 _source 필드를 감소시켰음을 주목하라. 검색 결과는 여전히 _source 필드 하나를 리턴하겠지만, 그 내에는 account_number, balance가 포함되어 있다.
SQL 배경지식이 있다면, 위의 예제는 SQL의 SELECT [필드 리스트] FROM…. 개념과 유사하다.
이제 query 파트로 이동해서 살펴보자. 앞전에 매칭되는 모든 document를 검색하는데 사용하는 match_all query를 살펴보았다. 이제 기본적인 field 지정 검색 query인 match query라고 불리는 새로운 query에 대해서 살펴보자. (특정 필드나 여러 필드에 대해서 검색 가능)
다음 예제는 20개의 account_number를 리턴한다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match":
{ "account_number": 20 } }
}'
다음 예제는 address에
"mill"을 포함하고 있는 account들을 리턴한다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match":
{ "address": "mill" } }
}'
다음 예제는 address에 "mill"이나 "lane"이 포함되어 있는 account들을 리턴한다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match":
{ "address": "mill lane" } }
}'
다음 예제는 address에 "mill lane" 절구가 포함되어 있는 모든 account들을 리턴한다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"match_phrase": { "address": "mill lane" }
}
}'
이제 bool query에 대해서 살펴 보자. Bool query의 boolean logic을 이용하여 더 큰 query에 작은 query들을 조합할 수 있다.
다음 예제는 2개의 match query를 조합하여 address에 "mill", "lane"을 모두 포함하고 있는 account를 리턴한다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must": [
{ "match": {
"address": "mill" } },
{ "match": {
"address": "lane" } }
]
}
}
}'
위의 예제에서 보면, bool must절은 query 내 match 대상이 되는 document가 모두 true이어야 함을 의미한다.
반대로, 다음 예제에서는 2개의 match절 중에 하나만 true이면 된다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"should": [
{ "match": {
"address": "mill" } },
{ "match": {
"address": "lane" } }
]
}
}
}'
위의 예제에서 bool should는 query내 match 대상이 되는 document가 true인 결과들의 모음이다.
(둘 중에 하나만 true인 경우의 결과를 모두 취합한 것과 같다)
다음 예제는 2개의 match query가 결합하여 address에 "mill"과 "lane"이 모두 없는 account들에 대한 결과를 리턴한다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must_not": [
{ "match": {
"address": "mill" } },
{ "match": {
"address": "lane" } }
]
}
}
}'
위의 예제에서 bool must_not 구절은 match 대상 document에 true가 없는 리스트를 리턴한다.
Bool query 내에 must, should, must_not 구절을 동시에 조합할 수 있다.
더욱이 bool 구절 내에 multi-level boolean logic을 가지는 복잡한 bool query를 구성할 수도 있다.
다음 예제는 40세, Live하지 않은 ID를 가진 모든 account를 리턴한다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must": [
{ "match": {
"age": "40" } }
],
"must_not": [
{ "match": {
"state": "ID" } }
]
}
}
}'
17. Exploring Your Data - Introducing the Query Language
Elastic Search/01. Getting Started 2015/04/22 17:05[Introducing the Query Language]
Elasticsearch는 query를 실행하는데 사용할 수 있는 JSON Style의 domain-specific language를 제공한다. 이것은 Query D니 (http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html) 을 참조하고 있다. Query language는 종합적이고, 처음에는 겁이 날 수도 있지만, 몇 가지 기본적인 예제를 통해서 실제적으로 배우기에는 가장 좋은 방법이다.
마지막 예제로 돌아가서 다음 Query를 실행해 보자.
{
"query": { "match_all": {} }
}
위의 query를 해부해 보면, query 파트는 query에 대한 정의를, match_all은 실행하고자 하는 query의 형태를 나타낸다. match_all query는 특정 index의 모든 document에 대한 검색을 나타낸다.
Query 파라미터에 더하여 검색 결과에 영향을 주는 다른 파라미터를 넘길 수도 있다. 예를 들면, 다음 예제는 match_all 결과 중에 첫번째 document만 리턴한다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"match_all": {} },
"size": 1
}'
size 값이 지정되지 않으면 기본적으로 10건을 리턴한다.
다음 예제는 11번째에서 20번째 document를 리턴한다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"match_all": {} },
"from": 10,
"size": 10
}'
from 파라미터 (0-based)는 시작지점을 의미하고, size 파라미터는 from 파라미터로부터 얼마나 많은 document를 리턴할 것인지를 의미한다. 검색 결과에 대한 paging을 구현할 때 유용하다. from이 없으면 default는 0이다.
다음 예제는 match_all을 수행하고 내림차순으로 account balance (계좌 잔액) 기준 정렬한 결과를 10개 (default) 리턴하는 예제이다.
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"match_all": {} },
"sort": {
"balance": { "order": "desc" } }
}'
댓글을 달아 주세요
댓글 RSS 주소 : http://www.yongbi.net/rss/comment/705