Page tree
Skip to end of metadata
Go to start of metadata

0. 사전 학습

1) DSL(Domain-specific language)

특정한 도메인을 적용하는데 특화된 컴퓨터 언어이다.
이는 어느 도메인에서나 적용 가능한 범용 언어(General-purpose language)와는 반대되는 개념이다.

2) 장점

도메인 특화 언어는 도메인 수준에서 검증, 확인이 가능하다.

언어의 구조가 안정적이라면, 그 언어에서 쓰여진 문장은 그 분야의 사람들이 이해하는데 불편함이 없다.

도메인 특화 언어는 비즈니스 정보 체계의 개발을 전통적인 소프트웨어 개발자들에게서 도메인에 깊은 지식을 가지고 있는

더 큰 도메인 전문가 그룹으로 옮기는데 도움을 준다.

3) 단점

새로운 언어를 배워야 한다는 초기 비용과 매우 좁은 적용분야.

도메인 특화 언어를 설계, 구현, 유지 하는데 드는 비용. 또한 그것으로 개발하기 위한 툴 개발 비용. 예제를 찾아보기 힘듦.

1. 개요

  •  Elasticsearch는 JSON에 기반한 full Query DSL(Domain Spectific Language)를 제공하여 쿼리를 정의 합니다.
    Leaf Query Clauses 와 Compound query clauses, 2가지 유형의 절로 구성 됩니다.
  • Leaf Query Clauses 는 match, term 또는 range 처럼 특정 필드에서 특정 값을 찾으며, 자체적으로 사용할 수 있습니다.
  • Compound query clauses 는 다른 leaf query 또는 Compound query 를 감싸고, bool 또는 dis_max 처럼 논리적인 방식으로 여러 쿼리를 결합 하는데 사용되어 지거나,
    constant_score 처럼 그들의 행동을 바구기 위해 사용되어 집니다.
    (bool, dis_max : 뒤에 설명, constant score 쿼리 : 전문 텍스트 쿼리는 가장 일치하는 도큐먼트를 찾기 위해 스코어링 메커니즘이 필요하지만
    constant score 쿼리를 사용하면 스코어가 없는 쿼리로 변환할 수 있음)
  • 쿼리 절은 query context 또는 filter context에 사용되는지 여부에 따라 다르게 동작 합니다.
    query context : 이 문서가 query와 얼마나 잘 일치 합니까?
    _score를 사용하여 다른 문서와 비교하여 얼마나 잘 일치 하는지를 나타냄
    filter context - 이 문서가 이 query 절과 일치 합니까? yes or no
    자주 사용되는 필터는 성능을 높이기 위해 Elasticsearch에 의해 자동으로 캐싱됨
    자세한 사항은 여기 참고 https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html


  • 쿼리 분류
  •  기본 쿼리(basci query) : 쿼리를 그룹핑해 분석................................................ 너무 많다. 이건 다음에 하자. ㅠ.ㅠ.

2. 데이터 준비

1) logstash가 설치된 디렉토리에 sample 폴더를 만들고 아래 url로 부터 파일을 다운로드

https://github.com/cheonjeongdae/elasticsearch/tree/master/sample/study_data.json

https://github.com/cheonjeongdae/elasticsearch/tree/master/sample/study_data.conf

https://github.com/cheonjeongdae/elasticsearch/tree/master/sample/study_data1.json

https://github.com/cheonjeongdae/elasticsearch/tree/master/sample/study_data1.conf

2) index 생성.

  •  kibana를 이용해서 아래 코드를 실행. curl로 실행해도 됨
slipp-study index
PUT /slipp-study
{
	"settings": {
		"index": {
			"number_of_replicas": "1",
			"number_of_shards": "1",
			"analysis": {
				"analyzer": {
					"std": {
						"type": "standard"
					}
				}
			}
		}
	},
	"mappings": {
		"accessLog": {
			"properties": {
				"accessPointId": {
					"type": "keyword",
					"fields": {
						"analyzed": {
							"type": "text"
						}
					}
				},
				"application": {
					"type": "keyword",
					"fields": {
						"analyzed": {
							"type": "text"
						}
					}
				},
				"band": {
					"type": "keyword",
					"fields": {
						"analyzed": {
							"type": "text"
						}
					}
				},
				"bandwidth": {
					"type": "double"
				},
				"category": {
					"type": "text",
					"analyzer": "std"
				},
				"customer": {
					"type": "keyword",
					"fields": {
						"analyzed": {
							"type": "text"
						}
					}
				},
				"department": {
					"type": "keyword",
					"fields": {
						"analyzed": {
							"type": "text"
						}
					}
				},
				"downloadCurrent": {
					"type": "double"
				},
				"downloadTotal": {
					"type": "integer"
				},
				"inactiveMs": {
					"type": "integer"
				},
				"location": {
					"type": "geo_point"
				},
				"mac": {
					"type": "keyword",
					"fields": {
						"analyzed": {
							"type": "text"
						}
					}
				},
				"networkId": {
					"type": "keyword",
					"fields": {
						"analyzed": {
							"type": "text"
						}
					}
				},
				"signalStrength": {
					"type": "integer"
				},
				"time": {
					"type": "date",
					"format": "strict_date_optional_time||epoch_millis"
				},
				"uploadCurrent": {
					"type": "double"
				},
				"uploadTotal": {
					"type": "integer"
				},
				"usage": {
					"type": "double"
				},
				"username": {
					"type": "keyword",
					"fields": {
						"analyzed": {
							"type": "text",
							"analyzer": "std"
						}
					}
				}
			}
		}
	}
}
slipp-study1 index
PUT /slipp-study1
{
	"settings": {
		"index": {
			"number_of_replicas": "1",
			"number_of_shards": "1",
			"analysis": {
				"analyzer": {
					"std": {
						"type": "standard"
					}
				}
			}
		}
	},
	"mappings": {
		"accessLog": {
			"properties": {
				"accessPointId": {
					"type": "keyword",
					"fields": {
						"analyzed": {
							"type": "text"
						}
					}
				},
				"application": {
					"type": "keyword",
					"fields": {
						"analyzed": {
							"type": "text"
						}
					}
				},
				"band": {
					"type": "keyword",
					"fields": {
						"analyzed": {
							"type": "text"
						}
					}
				},
				"bandwidth": {
					"type": "double"
				},
				"category": {
					"type": "text",
					"analyzer": "std"
				},
				"customer": {
					"type": "keyword",
					"fields": {
						"analyzed": {
							"type": "text"
						}
					}
				},
				"department": {
					"type": "text"
				},
				"downloadCurrent": {
					"type": "double"
				},
				"downloadTotal": {
					"type": "integer"
				},
				"inactiveMs": {
					"type": "integer"
				},
				"location": {
					"type": "geo_point"
				},
				"mac": {
					"type": "keyword",
					"fields": {
						"analyzed": {
							"type": "text"
						}
					}
				},
				"networkId": {
					"type": "keyword",
					"fields": {
						"analyzed": {
							"type": "text"
						}
					}
				},
				"signalStrength": {
					"type": "integer"
				},
				"time": {
					"type": "date",
					"format": "strict_date_optional_time||epoch_millis"
				},
				"uploadCurrent": {
					"type": "double"
				},
				"uploadTotal": {
					"type": "integer"
				},
				"usage": {
					"type": "double"
				},
				"username": {
					"type": "text",
					"analyzer": "std"
				}
			}
		}
	}
}


3) 실행

  • logstash 설치경로 bin>logstash.bat -f ../sample/study_data.conf
    * 1000건인데.... 왜 999건이 들어가지... ㅠ.ㅠ

4) 부연 설명

  •  type : text, 전문 텍스트 검색 유용, 토큰화가 되는 텍스트 필드. 예) a nice text
  •  type : keyword, 문자열 필드 분석이 가능한 데이터, 정렬, 필터링, 집계 기능을 지원. 토큰화가 안 되는 텍스트 필드. 예) CODE011
  • fields : 같은 필드를 다른 목적을 위해 다른 방법으로 처리돼야 하는 경우가 있다.
    예를 들어 문자열 필드가 검색을 위해 토큰화 처리가 필요하고, 정렬을 위해 비토큰화 처리가 필요하다.
    fields(예전에는 multi-field 라고 했고 지금은 fields 라고 함)를 정의해야 한다.
    fields 속성은 같은 필드를 여러 가지 방식으로 사용할 수 있는 매핑에 있어 매우 강력한 기능이다.
    https://www.elastic.co/guide/en/elasticsearch/reference/6.6/multi-fields.html

3 구조화된 데이터 검색

  • 결과에 어떤 항목이 포함되어 있는지 아닌지를 나타냄
  • 구조화된 검색 쿼리를 Term Level Query 라고 부름
  • 숫자와 날짜 및 시간 데이터 처럼 명확한 방법으로 예 또는 아니로 판별할 수 있는 데이터
  • 조건이 맞는 데이터가 있다면 쿼리 결과에 포함되고 없으면 빈값만 나옴
  • 국가 코드, 제품 코드 같은 식별자도 구조화된 데이터 등으로 사용할 수 있음


 

  • 왼쪽은 색인 시점에 발생하는 상황이고 오른쪽은 쿼리 시점에 발생하는 상황을 보여줌
  • keyword 타입 필드는 분석되지 않고, 해당 필드 값은 바로 역색인에 용어로 저장됨
  • 오른쪽 그림도 쿼리를 분석 과정을 건너 뛰고 역색인에서 바로 해당 용어를 검색함

1)  Range

  • 자연적 질서를 가진 데이터 타입에 적용할 수 있음.
  • 숫자 타입, 스코어 증폭(Score Boosting), 날짜  


GET /slipp-study1/_search
{
  "query": {
    "range": {
      "uploadTotal": {
        "gte": 700,
        "lte": 1000
      }
    }
  }
}
  • hits.max_score 1로 되어 있음. 중요도 혹은 유사도를 고려하지 않는 문서 스코어는 1로 표시  
  • 기본적으로 Range 쿼리는 각 도큐먼트에 스코어 1을 할당
  • boost 매개 변수를 제공해 결합한 쿼리와 비교해 스코어를 높힐 수 있음. 아래 쿼리 필터를 통과한 모든 도큐먼트 스코어가 2.2가 됨
    .... 생략
    "gte" : 10,
    "lte" : 20,
    "boost" : 2.2
  • 날짜는 기본적으로 정렬이 되기 때문에 Range 쿼리를 날짜에도 적용할 수 있음
  • 날짜 형식을 지정함
GET /slipp-study1/_search
{
  "query": {
    "range": {
      "time": {
        "gte": "2017/09/23 4:30:45",
        "lte": "2017/09/23 4:30:59",
        "format": "yyyy/MM/dd HH:mm:ss"
      }
    }
  }
}
  • 현재 시간을 나타내는 now를 사용할 수 있음
    "lte" : "now"
  • 기본적으로 Range 쿼리는 Filter Context 에서 실행됨

2) Exists

  • 특정 필드에 null 과 공백이 아닌 레코드만 가져오고 싶을때 유용하게 사용할 수 있음
  • 아래 예제에서는 username에 null 또는 공백이 아닌 모든 컬럼을 검색함
GET /slipp-study1/_search
{
  "query": {
    "exists": {
      "field": "username"
    }
  }
}


3) Term

  • type : text 필드에  용어 분석을 하지 않고 정확히 일치하는 도큐먼트를 찾음
  • 아래 예제를 보면 username은 검색이 되지 않지만, department는 검색이 된다. 이건 text 타입의 도큐먼트가 역색인 되면서 형태소 단위로 저장되어서
    매칭되는 데이터가 없다고 나오는거 같다.

    GET /slipp-study1/_search
    {
      "query": {
        "term": {
            "username": "Hong gilDong papa"
        }
      }
    }
    
    
    GET /slipp-study1/_search
    {
      "query": {
        "term": {
            "department": "develop"
        }
      }
    }


    kibana 템플릿은 왜 아래와 같이 field, value, value로 나오는지 모르겠다. 
    .... 생략 ......
    "query": {    
      "term": {       
        "FIELD": {         "value": "VALUE"       }     }   } }

GET /slipp-study1/_search
{
 "query": {
  "constant_score": {
   "filter": {
    "term": {
     "department": "develop"
    }
   }
  }
 }
}


4 전문 텍스트 검색

* 상위 레벨 쿼리(High-Level Query) : 전문 텍스트 쿼리는 구조화 되지 않은 텍스트 필드에 수행할 수 있으며, 이러한 쿼리는 분석 과정으로 인식함.
전문 텍스트 쿼리는 실제 검색 연산을 수행하기 전에 검색 용어를 대상으로 분석을 실행함 우선 필드 레벨에 search_analyzer가 정의됐는지 확인해 올바른 분석기를 찾아내고,
필드 레벨 분석기가 정의되지 않았다면 색인 레벨에서 정의된 분석기를 찾는다.
따라서 전문 텍스트 쿼리는 기본 필드에 분석 과정을 인식하고 실제 검색 쿼리를 구성하기 전에 올바른 분석 과정을 적용한다

  • 검색 요청하기
    GET /_search
    GET /index/_search
    GET /index/type_search
  • Query DSL은 Http 요청 메시지 본문에 JSON 으로 query 속성 값을 사용한다.

GET /_search
{
"query" : {.... 질의 ....}
}

  • 아래는 기본 옵션

1) match_all

  • 모든 문서와 매치함, 생략한 것과 결과가 같음

GET /_search
{
"query" : {
"match_all" : {}
}
예) "match_all": { "boost" : 1.2 }

  • "match_none": {} 은 match all의 반대 개념이다.

2) match

  • 대부분의 전문 텍스트 검색 요구 사항에 사용하는 기본 쿼리. 기본 필드에 사용된 분석기를 인식하는 상위 레벨 쿼리 중 하나
GET /slipp-study1/_search
{
	"query": {
		"match": {
			"username": "Melvin Test1"
		}
	}
}
  • 한글 깨지고, slipp-study, slipp-study1 의 차이점을 모르겠다. 
  • 적용 순서
    => 가장 일치하는 도큐먼트를 찾아 스코어에 따라 내림 차순으로 정렬
    => 도큐먼트가 같은 순서인 경우, 도큐먼트는 두 용어를 모두 갖고 있지만 같은 순서가 아니거나 서로 인접하지 않은 다른 도큐먼트 보다 더 높은 스코어를 가져야 함
    => 결과에 or 도 포함되나 낮은 스코어를 할당 한다.
    * slipp-study index 의 경우 적용 순서에 있는 것들이 잘 적용되지 않았다.
    fields 의 문제인지, 아님 다른 이슈가 있는지 원인을 찾지 못했다.
  • 몇가지 옵션이 있음

가. Operator
 Match 절의 기본 동작은 or 연산자를 사용해 결과를 결합한다.
Operator를 사용해 and 연산을 할 수 있다.

GET /slipp-study1/_search
{
	"query": {
		"match": {
			"username": {
				"query": "Melvin Test1",
				"operator": "and"
			}
		}
	}
}

나. minimum_should_match
or 연산자를 그대로 사용하되, 결과로 나오는 도큐먼트에서 일치하는 용어의 최소 개수를 지정할 수 있음

GET /slipp-study1/_search
{
	"query": {
		"match": {
			"username": {
				"query": "Melvin Test4",
				"minimum_should_match": "1"
			}
		}
	}
}

로 했을 때 결과는 2로 했을 때는 1개가 나오지만, 1로 했을때는 5개가 나옴

다. Fuzziness
레벤슈타인 거리(Levenshtein edit distance) 알고리즘을 기반으로 하며, 원본 문자열을 다른 문자열로 변경하기 위한 편집 횟수를 측정
편집은 원문 용어에 있는 문자의 삽입, 삭제, 대체, 치환을 의미함. 매개 변수는 0, 1, 2, AUTO 값 중 하나를 사용할 수 있음

GET /slipp-study1/_search
{
	"query": {
		"match": {
			"username": {
				"query": "Hogen aest1",
				"fuzziness": "1"
			}
		}
	}
}

Hogan => Hogen, Test1 => aest1 으로 검색했다. 1개가 틀린 글자 개수를 검색
일래스틱서치는 일치하는 용어를 추가로 만들어야 하므로 fuzziness 는 비용이 드는 작업
추가 매개 변수를 고려 해야 함
max_expansions : 확장 후 최대 용어 개수를 나타냄
prefix_length: 0, 1, 2 등의 숫자를 말함. fuzziness 검사 시작 시점을 prefix_length 매개 변수에 정의한 길이 이후로 지정


3) match phrase

  • 용어를 분해하지 않고, 일련의 단어를 일치시키는 쿼리. 인접한 단어가 정확한 순서를 갖는 단어를 찾을 때

    GET /slipp-study1/_search
    {
    	"query": {
    		"match_phrase": {
    			"username": {
    				"query": "Melvin Test",
    				"slop": 1
    			}
    		}
    	}
    }
  • slop 매개 변수를 지정하여 쿼리 시점에 건너 뛸 수 있는 단어 개수를 설정 할 수 있음
    0, 1, 2, 3 정수. 기본값은 0

4) match phrase_prefix

  • phrase 랑 같은데 마지막 단어랑 일치하는 것의 개수를 찾는다.
    default 값은 50이다. 아래 예제는 3을 줘서 처음 3개를 찾음

    GET /slipp-study1/_search
    {
    	"query": {
    		"match_phrase_prefix": {
    			"username": {
    				"query": "Test",
    				"max_expansions": 3
    			}
    		}
    	}
    } 


5) Multi Match

  • match 의 확장 버전으로 여러 필드에서 일치하는 쿼리를 실행 할 수 있음.
    다양한 옵션을 지정해 도큐먼트의 전체 스코어를 지정할 수 있음
    username 필드와 department 필드에서 develop or gilDong을 찾음

    GET /slipp-study1/_search
    {
    	"query": {
    		"multi_match": {
    			"query": "develop gilDong",
    			"fields": [
    				"username",
    				"department"
    			]
    		}
    	}
    }
  • 특정 필드의 스코어 높히기 위해 department에 2배를 해 주면 정렬되는 컬럼 순서가 달라짐

    GET /slipp-study1/_search
    {
    	"query": {
    		"multi_match": {
    			"query": "develop gilDong",
    			"fields": [
    				"username",
    				"department^2"
    			]
    		}
    	}
    }

6) wildcard 사용

  • 해석 되지 않는다. 
  •  * : 0개 이상의 문자가 매치 된다는 의미, ? : 한개 이상의 문자가 매치 된다는 의미 
  • integer 도 안되고... keyword 타입만 되는거 같다.
GET /slipp-study1/_search
{
  "query": {
    "wildcard": {
      "accessPointId": "AP-8C*08" 
    }
  }
}


5 복합 쿼리 작성

  • 하나 이상의 쿼리를 결합해 더 복잡한 쿼리를 작성할 때 사용함

1) Constant score

  • 일래스틱 서치는 구조화된 데이터와 전문 텍스트 쿼리를 지원합니다. 전문 텍스트 쿼리는 가장 일치하는 도큐먼트를 찾기 위해 스코어링 메카니즘이 필요하지만
    구조화된 데이터 검색은 스코어링이 필요 없습니다. Constant score를 사용하면 일반적으로 쿼리 컨텍스트에서 실행하는 스코어링 쿼리를
    필터 컨텍스트에서 실행하는 스코어가 없는 쿼리로 변환 할 수 있습니다. 
  • 스코어를 1로 할당하지 않고 boost 매개변수를 지정해 원하는 스코어를 지정할 수 있음.
    Bool 쿼리와 같이 다른 쿼리와 결합해서 사용하면 높은 스코어 값을 활용할 수 있음

2) Bool

  • 복잡한 쿼리를 작성하는데 유리
  • 다중 스코어링 및 스코어를 계산하지 않는 쿼리를 결합 할 수 있음
  • 아래와 같은 형태이다.
    must : query context에서 실행되는 스코어를 계산하는 쿼리. 지정된 쿼리가 반드시 true
    should : query context에서 실행되는 스코어를 계산하는 쿼리. 하나라도 만족하는 조건
    filter : filter context에서 실행되는 스코어를 계산하지 않는 쿼리
    must_not : filter context에서 실행되는 스코어를 계산하는 쿼리.
{
 "query": {
  "bool": {
   "must": [
    { 
    }
   ],
   "should": [
    {
    }
   ],
   "filter": {
   },
   "must_not": [
    {
    }
   ]
  }
 }
}
  • must 와 should 절을 포함한 쿼리는 query context에서 실행되고, 전체 Bool 쿼리는 filter context에 포함

가. OR 조건 결합

inactiveMs 가 2300 보다 크거나 department 가 develop 인 데이터를 검색

GET /slipp-study1/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "bool": {
          "should" : [
            {
              "range" : {
                "inactiveMs" : {
                  "gte" : 2300,
                  "lte" : 3000
                }
              }
            },
            {
              "term" : {
                "department" : "develop"
              }
            }
          ]
        }
      }
    }
  }
}

나. AND 및 OR 조건 결함

inactiveMs 가 2000 보다 크고, department 가 design 이거나 develop 인 경우

#! Deprecation: Should clauses in the filter context will no longer automatically set the minimum should match to 1 in the next major version. You should group them in a [filter] clause or explicitly set [minimum_should_match] to 1 to restore this behavior in the next major version.

GET /slipp-study1/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "bool": {
          "must" : [
            {
              "range" : {
                "inactiveMs" : {
                  "gte" : 2000,
                  "lte" : 3000
                }
              }
            }
          ],
          "should" : [
            {
              "term" : {
                "department" : "design"
              }
            },
            {
              "term" : {
                "department" : "develop"
              }
            }
          ]
        }
      }
    }
  }
}

다. NOT 조건 추가

inactiveMs 가 200 보다 크고 department가 develop 이 아닌 것

GET /slipp-study1/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "bool": {
          "must" : [
            {
              "range" : {
                "inactiveMs" : {
                  "gte" : 2000,
                  "lte" : 3000
                }
              }
            }
          ],
          "must_not" : [
            {
              "term" : {
                "department" : "develop"
              }
            }
          ]
        }
      }
    }
  }
}

must_not 요소를 사용하는 bool 쿼리는 쿼리를 무효화 하는데 유용하다.


3) Dis max

  • 불린 쿼리처럼 도큐먼트의 스코어가 모든 부분 쿼리의 합계를 얻는 것이 아닌 가장 높은 부스트 값을 얻는 부분 쿼리와 가장 많이 관련된 도큐먼트의 스코어를 얻을때 유용
  • 모든 하위 쿼리에서 리턴된 도큐먼트의 합집합을 생성하고 간단한 방정식인 max(일치하는 구문의 스코어) + tie_breaker * (최대 스코어가 아닌 다른 모든 구문의 스코어 합계)
    로 도큐먼트에 스코어링 작업을 진행
  • 쿼리를 필드마다 별도로 입력하는 것이 아니라 하나의 검색어를 여러 필드에 동시에 적용하여 점수 등을 구할때
    아래 코드가 username에만 나온다. analyzer를 적용안해서 department가 안 나올까? Test3 로 했을때도 안 나온다. 뭐가... 문제지.. ㅠ.ㅠ
GET /slipp-study1/_search
{
  "query": {
    "dis_max": {
      "tie_breaker": 0.7,
      "boost": 1.2,
      "queries": [
        {
          "match": {
            "username": "Test3 elastic"
          }
        },
        {
          "match": {
            "department": "Test3 elastic"
          }
        }
      ]
    }
  }
}


4) Function Score

  • 용어나 필드를 부스팅 하여 스코어를 조정하는 것은 한계를 가짐, 좀더 유연하게 스코어링을 조정할 수 있는 방식 
GET /slipp-study1/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "username": "Test2"
        }
      },
      "boost": "5",
      "random_score": {}, 
      "boost_mode":"multiply"
    }
  }
}


복잡하게 아래 처럼 사용할 수 도 있음
GET /slipp-study1/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "username": "This Hogan"
        }
      },
      "functions": [
        {
          "filter": {
            "range": {
              "downloadTotal": {
                "gte": 2200,
                "lte": 2500
              }
            }
          },
          "random_score": {},
          "weight": 20
        }
      ]
    }
  }
}

https://www.elastic.co/guide/en/elasticsearch/reference/6.6/query-dsl-function-score-query.html

5) Boosting

  • 색인 혹은 재색인시에 boost를 줄 수 있는데, 질의 시점에 부스팅을 사용하는걸 추천
GET /slipp-study1/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "username": "Test4 Hagan"
          }
        },
        {
          "range": {
            "uploadTotal": {
                "gte": 900,
                "lte": 99900,
                "boost": 5
            }
          }
        }
      ]
    }
  }
}

6) Indices

  • index 들의 복수 묶음 
  • 몰라... 몰라... 몰라..... ㅠ.ㅠ


6 filter context

  • 성능을 위해서 필터를 먼저 한 뒤에 쿼리를 하는 것이 효과적이다.

1) bool 

  • filtered 가 bool 로 변경 되었음
  • filter 라는 것이 6.x 버전과 이전 버전에 사용법이 다른거 같다.
GET /slipp-study1/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "username": "Hogan"
          }
        }
      ],
      "filter": {
        "range": {
          "uploadTotal": {
            "gte": 800,
            "lte": 1000
          }
        }
      }
    }
  }
}


2) terms

  • term filter 와 같지만 복수의 값을 배열로 지정할 수 있음
GET /slipp-study1/_search
{
  "query": {
    "terms": {
      "department": [
        "develop",
        "design"
      ]
    }
  }
}


7 정렬

  • query를 match 고 정렬을 하니 안되는데....... range로 query 날리고 정렬하면 잘 된다. 이유가 뭘까? 
GET /slipp-study1/_search
{
  "query": {
    "range": {
      "uploadTotal": {
        "gte": 700,
        "lte": 1000
      }
    }
  },
  "sort": [
    {
      "inactiveMs": {
        "order": "asc"
      }
    }
  ]
}


8 검색 결과 필드 가공

1) _source

  • kibana에서 원하는 필드만 보고 싶을때 예전 버전에서는 fields를 사용하라고 하는데.... 하면 오류 나고..... 아래와 같이 하면 된다. 맞는지 모르겠다.
GET /slipp-study1/_search
{
  "_source": {
    "includes": ["username", "department", "uploadTotal"]
  },
  "query": {
    "range": {
      "uploadTotal": {
        "gte": 700,
        "lte": 1000
      }
    }
  }
}





















  • No labels

2 Comments

  1. Sort를 하기 위해서는 Query와 Sort 따로 나눠서 작성한다.

    must / terms / high

    Search Profiler 는 실행한 쿼리에 대한 검증&시간을 체크할 수 있다.

  2. 집계는 추후 진행.