DSL쿼리를 공부해본다! 앞 쪽 부분이어서 aggregation들어가기 전에는 난이도가 비교적 쉽다.
앞서, DSL이 어떤 약자인지 궁금해서 검색해봤다.
DSL = Domain Specific Language
이다.
이런 약어는 무조건 풀어서 알아두는게 좋다고 생각한다.
그래야 기억에 오래 남는다.
본 포스팅에서는 match 관련 쿼리를 사용해 본다.
요청 url은 모두 GET http://localhost:9200/bank/_search
로 동일하다.
해당 인덱스의 모든 쿼리를 리턴해준다.
{
"query":{
"match_all":{ }
}
}
가장 일반적인 쿼리문, 뜻 그대로 매치되냐 ? 이다.
match 속성을 쿼리 속성 안에 기재 후, 원하는 내용이 들어갈 필드와 원하는 내용을 아래와 같이 기재한다.
나는 city 필드가 Brogan 인 데이터를 찾고싶었다.
{
"query": {
"match": {
"city": "Brogan"
}
}
}
결과는 다음과 같다.
{
"took": 1992,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 6.5059485,
"hits": [
{
"_index": "bank",
"_type": "account",
"_id": "1",
"_score": 6.5059485,
"_source": {
"account_number": 1,
"balance": 39225,
"firstname": "Amber",
"lastname": "Duke",
"age": 32,
"gender": "M",
"address": "880 Holmes Lane",
"employer": "Pyrami",
"email": "amberduke@pyrami.com",
"city": "Brogan",
"state": "IL"
}
}
]
}
}
단어 2개 이상일 경우에는 조건이 있다.
기본적으로 or 로 검색하게 된다. 둘중에 하나라도 일치하게 되면 추출된다.
두개 모두 일치하면 score가 높은 점수로 추출되고,
두개 중 하나만 일치하면 score가 낮은 점수로 추출된다.
{
"query": {
"match": {
"address": "Crystal Street"
}
}
}
{
"took": 1570,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 385,
"relation": "eq"
},
"max_score": 7.455468,
"hits": [
{
"_index": "bank",
"_type": "account",
"_id": "964",
"_score": 7.455468,
"_source": {
"account_number": 964,
"balance": 26154,
"firstname": "Elena",
"lastname": "Waller",
"age": 34,
"gender": "F",
"address": "618 Crystal Street",
"employer": "Insurety",
"email": "elenawaller@insurety.com",
"city": "Gallina",
"state": "NY"
}
},
{
"_index": "bank",
"_type": "account",
"_id": "6",
"_score": 0.95395315,
"_source": {
"account_number": 6,
"balance": 5686,
"firstname": "Hattie",
"lastname": "Bond",
"age": 36,
"gender": "M",
"address": "671 Bristol Street",
"employer": "Netagy",
"email": "hattiebond@netagy.com",
"city": "Dante",
"state": "TN"
}
},
{
"_index": "bank",
"_type": "account",
"_id": "13",
"_score": 0.95395315,
"_source": {
"account_number": 13,
"balance": 32838,
"firstname": "Nanette",
"lastname": "Bates",
"age": 28,
"gender": "F",
"address": "789 Madison Street",
"employer": "Quility",
"email": "nanettebates@quility.com",
"city": "Nogal",
"state": "VA"
}
},
{
"_index": "bank",
"_type": "account",
"_id": "32",
"_score": 0.95395315,
"_source": {
"account_number": 32,
"balance": 48086,
"firstname": "Dillard",
"lastname": "Mcpherson",
"age": 34,
"gender": "F",
"address": "702 Quentin Street",
"employer": "Quailcom",
"email": "dillardmcpherson@quailcom.com",
"city": "Veguita",
"state": "IN"
}
}
]
}
}
{
"query": {
"match": {
"address": {
"query": "Crystal Street",
"operator": "and"
}
}
}
}
결과는 다음과 같다.
{
"took": 535,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 7.455468,
"hits": [
{
"_index": "bank",
"_type": "account",
"_id": "964",
"_score": 7.455468,
"_source": {
"account_number": 964,
"balance": 26154,
"firstname": "Elena",
"lastname": "Waller",
"age": 34,
"gender": "F",
"address": "618 Crystal Street",
"employer": "Insurety",
"email": "elenawaller@insurety.com",
"city": "Gallina",
"state": "NY"
}
}
]
}
}
근데 여기서 주의해야 할 점이 있다.
지금은 주소가 붙어서 나와있지만, 실제로는
Crystal Test Address 이런 주소여도 매칭되어 나오게 된다.
즉, 토큰단위로 true/false를 검색한다고 생각하면 된다.
앞선 문제점을 해결하기 위해 나온 쿼리 옵션이다.
말 그대로 Crystal Address 자체를 찾는 것이다. 나는 현업에서 로그 데이터를 필터링 하기 위해 매치 프레이스를 많이 썼던 것으로 기억한다. 쿼리스트링도 많이 쓰지만, 매치 프레이스가 그냥 깔끔하고 간단하고 쉽다....
match_phrase 예시를 사용하기 위해서 이 홈페이지에 나와있는 샘플 데이터를 사용했다.
그리고, lazy dog를 검색했다.
{
"query": {
"match_phrase": {
"message": "lazy dog"
}
}
}
결과는 다음과 같다.
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.9489645,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.9489645,
"_source" : {
"message" : "The quick brown fox jumps over the lazy dog"
}
}
]
}
}
+) 추가로, slop옵션을 사용해서 lazy dog 사이에 n개 이상의 단어를 허용할 수 있다.
{
"query": {
"match_phrase": {
"message": {
"query": "lazy dog",
"slop": 1
}
}
}
}
결과는 다음과 같다.
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0110221,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "5",
"_score" : 1.0110221,
"_source" : {
"message" : "Lazy jumping dog"
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.9489645,
"_source" : {
"message" : "The quick brown fox jumps over the lazy dog"
}
}
]
}
}
다음은 bool쿼리를 알아보도록 하자.