5.1 풀 텍스트 쿼리 - Full Text Query
이 문서의 허가되지 않은 무단 복제나 배포 및 출판을 금지합니다. 본 문서의 내용 및 도표 등을 인용하고자 하는 경우 출처를 명시하고 김종민([email protected])에게 사용 내용을 알려주시기 바랍니다.
Elastcisearch 검색에 사용되는 주요 쿼리들을 살펴보도록 하겠습니다. 예제들을 실행하기 위해 my_index 인덱스에 다음의 5개 도큐먼트를 먼저 입력하도록 하겠습니다.
my_index 인덱스에 벌크로 데이터 입력
1
POST my_index/_bulk
2
{"index":{"_id":1}}
3
{"message":"The quick brown fox"}
4
{"index":{"_id":2}}
5
{"message":"The quick brown fox jumps over the lazy dog"}
6
{"index":{"_id":3}}
7
{"message":"The quick brown fox jumps over the quick dog"}
8
{"index":{"_id":4}}
9
{"message":"Brown fox brown dog"}
10
{"index":{"_id":5}}
11
{"message":"Lazy jumping dog"}
Copied!
이후에 나올 예제들을 확인하기 위해 위에 색인된 도큐먼트들의 message 필드 값의 내용들은 다른 에디터나 노트 등에 적어놓고 같이 보는 것이 편리합니다.

match_all

match_all 은 별다른 조건 없이 해당 인덱스의 모든 도큐먼트를 검색하는 쿼리입니다. 검색 시 쿼리를 넣지 않으면 elasticsearch는 자동으로 match_all을 적용해서 해당 인덱스의 모든 도큐먼트를 검색합니다. 다음 두 예제는 결과가 동일합니다.
쿼리 없이 실행
match_all 쿼리로 실행
1
GET my_index/_search
Copied!
1
GET my_index/_search
2
{
3
"query":{
4
"match_all":{ }
5
}
6
}
7
Copied!

match

match 쿼리는 풀 텍스트 검색에 사용되는 가장 일반적인 쿼리입니다. 다음은 match 쿼리를 이용하여 my_index 인덱스의 message 필드에 dog 가 포함되어 있는 모든 문서를 검색합니다.
request
response
match 쿼리로 message 필드에서 dog 검색
1
GET my_index/_search
2
{
3
"query": {
4
"match": {
5
"message": "dog"
6
}
7
}
8
}
Copied!
match 쿼리로 message 필드에서 dog 검색 결과
1
{
2
"took" : 1,
3
"timed_out" : false,
4
"_shards" : {
5
"total" : 1,
6
"successful" : 1,
7
"skipped" : 0,
8
"failed" : 0
9
},
10
"hits" : {
11
"total" : {
12
"value" : 4,
13
"relation" : "eq"
14
},
15
"max_score" : 0.35847884,
16
"hits" : [
17
{
18
"_index" : "my_index",
19
"_type" : "_doc",
20
"_id" : "5",
21
"_score" : 0.35847884,
22
"_source" : {
23
"message" : "Lazy jumping dog"
24
}
25
},
26
{
27
"_index" : "my_index",
28
"_type" : "_doc",
29
"_id" : "4",
30
"_score" : 0.32951736,
31
"_source" : {
32
"message" : "Brown fox brown dog"
33
}
34
},
35
{
36
"_index" : "my_index",
37
"_type" : "_doc",
38
"_id" : "2",
39
"_score" : 0.23470737,
40
"_source" : {
41
"message" : "The quick brown fox jumps over the lazy dog"
42
}
43
},
44
{
45
"_index" : "my_index",
46
"_type" : "_doc",
47
"_id" : "3",
48
"_score" : 0.23470737,
49
"_source" : {
50
"message" : "The quick brown fox jumps over the quick dog"
51
}
52
}
53
]
54
}
55
}
Copied!
dog가 포함된 총 4개의 도큐먼트가 검색 결과로 나타납니다.
match 검색에 여러 개의 검색어를 집어넣게 되면 디폴트로 OR 조건으로 검색이 되어 입력된 검색어 별로 하나라도 포함된 모든 문서를 모두 검색합니다. 다음은 검색어로 quick dog 를 검색 한 결과입니다.
request
response
match 쿼리로 message 필드에서 quick dog 검색
1
GET my_index/_search
2
{
3
"query": {
4
"match": {
5
"message": "quick dog"
6
}
7
}
8
}
Copied!
match 쿼리로 message 필드에서 quick dog 검색 결과
1
{
2
"took" : 2,
3
"timed_out" : false,
4
"_shards" : {
5
"total" : 1,
6
"successful" : 1,
7
"skipped" : 0,
8
"failed" : 0
9
},
10
"hits" : {
11
"total" : {
12
"value" : 5,
13
"relation" : "eq"
14
},
15
"max_score" : 0.8762741,
16
"hits" : [
17
{
18
"_index" : "my_index",
19
"_type" : "_doc",
20
"_id" : "3",
21
"_score" : 0.8762741,
22
"_source" : {
23
"message" : "The quick brown fox jumps over the quick dog"
24
}
25
},
26
{
27
"_index" : "my_index",
28
"_type" : "_doc",
29
"_id" : "2",
30
"_score" : 0.6744513,
31
"_source" : {
32
"message" : "The quick brown fox jumps over the lazy dog"
33
}
34
},
35
{
36
"_index" : "my_index",
37
"_type" : "_doc",
38
"_id" : "1",
39
"_score" : 0.6173784,
40
"_source" : {
41
"message" : "The quick brown fox"
42
}
43
},
44
{
45
"_index" : "my_index",
46
"_type" : "_doc",
47
"_id" : "5",
48
"_score" : 0.35847884,
49
"_source" : {
50
"message" : "Lazy jumping dog"
51
}
52
},
53
{
54
"_index" : "my_index",
55
"_type" : "_doc",
56
"_id" : "4",
57
"_score" : 0.32951736,
58
"_source" : {
59
"message" : "Brown fox brown dog"
60
}
61
}
62
]
63
}
64
}
65
Copied!
quick과 dog중 어떤 단어라도 포함한 도큐먼트 총 5개가 검색되었습니다.
검색어가 여럿일 때 검색 조건을 OR 가 아닌 AND 로 바꾸려면 operator 옵션을 사용할 수 있습니다. 이 경우 문법이 조금 달라지는데, <필드명>:<검색어> 형식으로 하던 것을 <필드명>: { "query":<검색어>, "operator": } 와 같이 입력해야 합니다. quick dogAND 조건으로 검색하려면 다음과 같습니다.
request
response
match 쿼리 AND 조건으로 quick dog 검색
1
GET my_index/_search
2
{
3
"query": {
4
"match": {
5
"message": {
6
"query": "quick dog",
7
"operator": "and"
8
}
9
}
10
}
11
}
Copied!
match 쿼리 AND 조건으로 quick dog 검색 결과
1
{
2
"took" : 6,
3
"timed_out" : false,
4
"_shards" : {
5
"total" : 1,
6
"successful" : 1,
7
"skipped" : 0,
8
"failed" : 0
9
},
10
"hits" : {
11
"total" : {
12
"value" : 2,
13
"relation" : "eq"
14
},
15
"max_score" : 0.8762741,
16
"hits" : [
17
{
18
"_index" : "my_index",
19
"_type" : "_doc",
20
"_id" : "3",
21
"_score" : 0.8762741,
22
"_source" : {
23
"message" : "The quick brown fox jumps over the quick dog"
24
}
25
},
26
{
27
"_index" : "my_index",
28
"_type" : "_doc",
29
"_id" : "2",
30
"_score" : 0.6744513,
31
"_source" : {
32
"message" : "The quick brown fox jumps over the lazy dog"
33
}
34
}
35
]
36
}
37
}
Copied!

match_phrase

match 쿼리에서 quick 과 dog 검색어를 AND 조건으로 검색하는 방법을 알아보았습니다. 그런데 "quick dog" 라는 구문을 공백을 포함해 정확히 일치하는 내용을 검색하려면 어떻게 해야 할까요? 바로 match_phrase 쿼리를 사용하면 됩니다. match_phrase 쿼리는 입력된 검색어를 순서까지 고려하여 검색을 수행합니다. 다음은 lazy dog 라는 구문을 검색하는 match_phrase 쿼리입니다.
request
response
match_phrase 쿼리로 "lazy dog" 구문 검색
1
GET my_index/_search
2
{
3
"query": {
4
"match_phrase": {
5
"message": "lazy dog"
6
}
7
}
8
}
Copied!
match_phrase 쿼리로 "lazy dog" 구문 검색 결과
1
{
2
"took" : 1,
3
"timed_out" : false,
4
"_shards" : {
5
"total" : 1,
6
"successful" : 1,
7
"skipped" : 0,
8
"failed" : 0
9
},
10
"hits" : {
11
"total" : {
12
"value" : 1,
13
"relation" : "eq"
14
},
15
"max_score" : 0.9489645,
16
"hits" : [
17
{
18
"_index" : "my_index",
19
"_type" : "_doc",
20
"_id" : "2",
21
"_score" : 0.9489645,
22
"_source" : {
23
"message" : "The quick brown fox jumps over the lazy dog"
24
}
25
}
26
]
27
}
28
}
Copied!
"lazy dog" 라는 정확한 문장이 포함된 도큐먼트 1개만 검색이 되었습니다.
match_phrase 쿼리는 slop 이라는 옵션을 이용하여 slop에 지정된 값 만큼 단어 사이에 다른 검색어가 끼어드는 것을 허용할 수 있습니다. slop을 1로 하고 검색을 하면 다음과 같은 결과가 나옵니다.
request
response
match_phrase 쿼리에 slop:1 로 "lazy dog" 구문 검색
1
GET my_index/_search
2
{
3
"query": {
4
"match_phrase": {
5
"message": {
6
"query": "lazy dog",
7
"slop": 1
8
}
9
}
10
}
11
}
Copied!
match_phrase 쿼리에 slop:1 로 "lazy dog" 구문 검색 결과
1
{
2
"took" : 3,
3
"timed_out" : false,
4
"_shards" : {
5
"total" : 1,
6
"successful" : 1,
7
"skipped" : 0,
8
"failed" : 0
9
},
10
"hits" : {
11
"total" : {
12
"value" : 2,
13
"relation" : "eq"
14
},
15
"max_score" : 1.0110221,
16
"hits" : [
17
{
18
"_index" : "my_index",
19
"_type" : "_doc",
20
"_id" : "5",
21
"_score" : 1.0110221,
22
"_source" : {
23
"message" : "Lazy jumping dog"
24
}
25
},
26
{
27
"_index" : "my_index",
28
"_type" : "_doc",
29
"_id" : "2",
30
"_score" : 0.9489645,
31
"_source" : {
32
"message" : "The quick brown fox jumps over the lazy dog"
33
}
34
}
35
]
36
}
37
}
Copied!
slop의 크기를 1로 했기 때문에 lazy와dog 사이에 jumping이 있는 "Lazy jumping dog" 값도 검색이 됩니다. slop을 2로 한다면 아마도 lazy jumping brow dog 같은 문장도 검색에 포함될 수 있을 것입니다.
이처럼 match_phrase 쿼리와 slop을 이용하면 정확도를 조절 해 가며 원하는 검색 결과의 범위를 넓힐 수 있습니다. slop을 너무 크게 하면 검색 범위가 넓어져 관련이 없는 결과가 나타날 확률도 높아지기 때문에 1 이상은 사용하지 않는 것을 권장 드립니다.

query_string

4.4 검색 API 장에서 URL의 q 파라메터를 이용해서 검색을 수행하는 것을 설명했습니다. URL검색에 사용하는 루씬의 검색 문법을 본문 검색에 이용하고 싶을 때 query_string 쿼리를 사용할 수 있습니다.
다음은 message 필드에서 lazyjumping을 모두 포함하거나 또는 "quick dog" 구문을 포함하는 도큐먼트를 검색하는 쿼리입니다. match_phrase 처럼 구문 검색을 할 때는 검색할 구문을 쌍따옴표 \" 안에 넣습니다.
request
response
query_string 쿼리 검색
1
GET my_index/_search
2
{
3
"query": {
4
"query_string": {
5
"default_field": "message",
6
"query": "(jumping AND lazy) OR \"quick dog\""
7
}
8
}
9
}
Copied!
query_string 쿼리 검색 결과
1
{
2
"took" : 3,
3
"timed_out" : false,
4
"_shards" : {
5
"total" : 1,
6
"successful" : 1,
7
"skipped" : 0,
8
"failed" : 0
9
},
10
"hits" : {
11
"total" : {
12
"value" : 2,
13
"relation" : "eq"
14
},
15
"max_score" : 2.818369,
16
"hits" : [
17
{
18
"_index" : "my_index",
19
"_type" : "_doc",
20
"_id" : "5",
21
"_score" : 2.818369,
22
"_source" : {
23
"message" : "Lazy jumping dog"
24
}
25
},
26
{
27
"_index" : "my_index",
28
"_type" : "_doc",
29
"_id" : "3",
30
"_score" : 0.67445135,
31
"_source" : {
32
"message" : "The quick brown fox jumps over the quick dog"
33
}
34
}
35
]
36
}
37
}
Copied!
"Lazy jumping dog" 도큐먼트와 "quick dog" 값을 포함하는 도큐먼트 두개가 결과로 리턴된 것을 확인할 수 있습니다.