본문 바로가기

데이터베이스(DA, AA, TA)/NoSQL

[ELK] 엘라스틱서치 배우기 - 검색API

ElasticSearch에서의 검색은 인덱스/타입 단위로 수행됨. Document는 그 자체가 1개의 최소 데이터 단위이므로 Document 단위로 검색한다는 것은 불가능. 


클러스터의 모든 인덱스는 _all 로 검색 가능.


$ curl 'localhost:9200/_all/_search?q=time&pretty'




ElasticSearch URI 검색


q(query)

특정 필드만 검색하려면 q 매개변수에 필드명:질의어 형식으로 값을 일력한다. title 필드에서 검색어 time을 검색하는 명령


$ curl 'localhost:9200/_search?q=title:time&pretty'


$ curl 'localhost:9200/_search?q=title:time%20AND%20machine&pretty'



df(default field)

q 질의에 필드명을 넣는 대신 df 매개변수를 사용해서 검색할 필드 지정 가능


$ curl 'localhost:9200/_search?q=time&df=title&pretty'



explain

각 검색 처리에 해당 검색 셜과의 점수 계산에 사용된 상세 값이 출력 결과에 표시됨. 점수는 검색어에 해당하는 데이터의 정확도를 계산한 값(정보검색 이론에서 Scoring 개념을 참고하면 될듯)이며, 기본적으로 점수가 높을수록 결과밧의 상위에 랭크


$ curl 'localhost:9200/_search?q=title:time&explain&pretty'



_source

_source 매개변수의 값을 false로 설정하면 검색 결과에서 도큐먼트 내용은 표시하지 않고 전체 hit수와 score 등의 메타 정보만 출력.


$ curl 'localhost:9200/_search?q=title:time&_source=false&pretty'



fields

fields 매개변수로 출력 결과에 표시할 필드 지정 가능. 표시할 필드를 쉼표(,)로 구분해서 입력


$ curl 'localhost:9200/_search?q=title:time&fields=title,author,category&pretty'



sort

sort 매개변수를 사용해서 검색 결과의 출력 순서 지정 가능. default는 _score 값을 기준으로 정렬됨. 정렬할 기준을 변경하려면 sort=필드명 형식으로 지정. 기본적으로 오름차순으로 정렬되며 sort=필드명:asc를 입력해도 같은 결과가 출력됨. 내림차순으로 정렬하려면 sort=필드명:desc를 입력


$ curl 'localhost:9200/books/_search?q=author:jules&sort=pages:desc&pretty'


title 필드의 값 전체를 대상으로 정렬하고 싶다면 데이터를 색인하기 전에 title 필드를 not_analyzed로 매핑 설정해 줘야함. sort 매개변수로 정렬할 필드를 지정하면 _score의 값이 null로 설정되고 이는 정렬하기 위해 결과값을 _score값으로 비교할 필요가 없기 때문임. sort 매개변수를 사용한 후에도 _score값을 출력하기를 원한다면 track_scores=true 매개변수를 추가하면 됨.



timeout

timeout 매개변수로 검색이 수행되는 동안 기다리는 제한 시간을 지정할 수 있음. 지정하지 않으면 제한시간없이 전체 결과가 나올때까지 기다리게됨. timeout=3000으로 지정하면 검색을 시작하고 3초 후에 검색을 강제 종료하고 검색한 결과를 표시.



from

from 매개변수는 검색된 결과를 몇번째 값부터 출력할지 지정. 지정하지 않으면 기본값은 0이 됨. 검색 결과로 10건이 검색됐는데 from=3으로 지정했다면 4번째부터 도큐먼트가 표시된다.


$ curl 'localhost:9200/books/_search?q=author:jules&fields=title&from=1&pretty'



size

size 매개변수는 검색된결과 도큐먼트를 몇개까지 표시할지 지정. 지정하지 않으면 기본값은 10이다. 더 많은 document를 출력해야 한다면 size 매개변수를 사용해서 조절한다. 주의할 점은 ElasticSearch가 전송하는 데이터 용량에 제한이 있는 경우 너무 많은 내용의 결과를 출력하려 할 때 오류가 발생할 수 있다. 관련 설정은 config/elasticsearch.yml에서 http.max_content_length 설정을 참고한다.


from과 size 매개변수를 함께 사용하면 페이징 기능을 구현할 수 있다. from으로 몇번째 페이지를 출력할지 정하고 size로 한 페이지에 출력할 결과 수를 지정하면 된다.



search_type

query_then_fetch: 전체 샤드의 검색이 다 수행된 후에 결과를 출력한다. 전체 취합된 결과를 size 매개변수에서 지정한 개수만큼 출력

query_and_fetch: 샤드별로 검색되는 대로 결과를 받아 출력한다. size 매개변수에서 지정한 개수만큼 샤드별로 검색하므로 size가 10이고 샤드의 개수가 5라면 전체 출력 결과는 샤드당 10개씩 총 50개의 도큐먼트가 출력

dfs_query_then_fetch: 검색 방식은 query_then_fetch와 같으며 정확한 scoring을 위해 검색어들을 사전 처리한다.

dfs_query_and_fetch: 검색 방식은 query_and_fetch와 같으며 정확한 scoring을 위해 검색어들을 사전 처리한다.

count: 검색된 도큐먼트 정보를 배제하고 전체 hits 수만 출력한다. 속도가 가장 빠르다.

scan: scroll과 같이 사용되며 검색결과를 바로 보여주지 않고 scroll에 저장했다가 _scroll_id를 사용해서 나중에 결과를 출력한다. 검색 방식은 query_and_fetch와 같음.





ElasticSearch RequestBody 검색


ElasticSearch에서 검색할 조건을 JSON 데이터 형식의 질의로 입력해서 사용할 수 있다. 이러한 방식의 검색을 Request Body 검색이라고 하며 URI 검색보다 더 복잡한 형식으로 검색할 수 있다.


Request Body 검색은 ElasticSearch의 질의 언어인 QueryDSL을 사용한다. QueryDSL에는 match, term, range 등의 다양한 질의가 존재한다. Request 검색의 형태는 다음과 같다.


<호스트>:<포트>/<?인덱스>/<?타입>/_search -d '

{

<옵션>:<값>, ...

"query": {

... <질의 문법> ...

}

}



다음은  books 인덱스에서 author가 william인 값을 검색하는 내용의 Term쿼리 예제이다.


$ curl 'localhost:9200/books/_search?pretty' -d '

{

"query": {

"term": {"author" : "william"}

}

}'



size, from, field

URI 검색에서 사용했던 size, from, field 등의 매개변수를 옵션으로 지정할 수 있음. query에서 전체 필드를 검색하려면 필드명에 _all을 입력한다. 


$ curl 'localhost:9200/_search?pretty' -d '

{

from: 1,

size:2,

fields : ["title", "category"],

query: {

term: {"_all" : "time"}

}

}'



sort

sort 옵션을 사용해서 검색 결과의 출력 순서를 정할 수 있다. 기본적으로 검색 결과의 출력은 _score 값을 기준으로 정렬된다. 배열로 정렬할 필드를 여러개 지정할 수도 있다. 또한 asc, desc 옵션으로 오름차순, 내림차순 정렬을 지정할 수 있으며 기본값은 오름차순이다.


$ curl 'localhost:9200/books/_search?pretty' -d '

{

"fields" : ["title", "author", "category", "pages"],

"sort" : [{"category":"desc"}, "pages", "title"],

"query": {

"term" : {"_all" : "time"}

}

}'


오름차순, 내림차순은 order 필드로 지정할 수 있다. 이 외에도 배열로 여러 개의 값을 가진 필드는 mode 필드를 이용해 해당 필드의 특정 값을 지정해서 sort에 사용할 수 있다. mode 필드에 지정할 수 있는 값은 다음과 같다.


min - 해당 필드의 값 중 최솟값을 선택

max - 해당 필드의 값 중 최댓값을 선택

avg - 해당 필드 값의 평균값을 대입. 필드 값이 number일때에만 유효함

sum - 해당 필드 값의 합계를 대입. 필드 값이 number일 때에만 유효함


다음은 category 필드의 sort 값을 mode를 이용하여 검색한 예제이다.


$ curl 'localhost:9200/books/_search?pretty' -d '

{

"fields": ["title", "author", "category", "pages"],

"sort": [{"category":{"order":"desc", "mode":"min"}}, "pages", "title"],

"query": {

"term": {"category":"science"}

}

}'


sort에서 지정한 필드가 존재하지 않으면 원래는 검색에 실패하게 되나, ignore_unmapped 필드를 true로 설정하면 존재하지 않는 필드는 무시한 채 검색을 진행한다.


특정 필드로 sort를 실행하면 점수가 표시되지 않는다. track_scores 필드를 true로 설정하고 실행하면 점수가 표시된다.



_source

_source 필드 값을 false로 설정하면 검색 결과 도큐먼트 내용은 표시하지 않고 전체 hit 수와 점수 등의 메타 정보만 출력된다. _source 값으로 false가 아닌 필드명을 입력하면 입력된 필드들의 값만 표시된다. 필드명은 *, ? 기호를 이용한 와일드카드를 사용할 수 있으므로 obj.*와 같이 특정 레벨 이하의 값을 출력하는 등의 ㅎ여식으로도 지정할 수 있다.


$ curl 'localhost:9200/magazines/_search?pretty' -d '

{

"_source": ["title", "c*"]

}'


include, exclude 필드를 사용하면 특정 패턴의 필드를 포함하거나 배제할 수 있다.



partial_fields, fielddata_fields

fields 옵션을 이용해 지정한 필드들만 출력할 수 있지만, fields 옵션은 _source와 달리 기본적으로는 와일드 카드를 지정할 수 있다.