반응형
출처: https://www.elastic.co/guide/en/elasticsearch/reference/current/full-text-queries.html
출처: https://stackoverflow.com/questions/26001002/elasticsearch-difference-between-term-match-phrase-and-query-string

1. term

하나의 term을 찾는다. 이 term은 analyze 되지 않는다. 따라서 대소문자, 복수형 등이 다 구분된다

{ "user":"Bennett" }

{
  "query": {
    "term" : { "user" : "bennett" }
  }
}
//아무것도 리턴되지 않는다. (대소문자 구분)

 

2. match

가장 기본적인 search로 text, number, date, boolean을 사용할 수 있다. text는 검색하기전 analyze된다.

fuzzy matching을 지원한다(정확하게 일치하지않더라도 연관성이 있다고 판단하면 리턴).

GET /_search
{
    "query": {
        "match" : {
            "message" : {
                "query" : "this is a test"
            }
        }
    }
}

 

3. query_string

입력값을 analyze한다. 사용자가 명시적으로 ""로 둘러싸지않는이상 순서는 상관이 없다.

{ "foo":"I just said hello world" }
{ "foo":"Hello world" }
{ "foo":"World Hello" }

{
  "query": {
    "query_string": {
      "query": "hello World"
    }
  }
}
//얘는 3개를 다 리턴한다

{
  "query": {
    "query_string": {
      "query": "\"Hello World\""
    }
  }
}
//얘는 명시적으로 ""로 싸여져 있기 때문에 match_phrase와 동일하게 처음 2개만을 리턴한다.

query_string과 match의 차이점은 AND와 OR같은 연산자를 사용할 수 있다. 

query_string은 syntax를 먼저 parse한 뒤에 split을 하고 analyze를 한다.

GET /_search
{
    "query": {
        "query_string" : {
            "query" : "(new york city) OR (big apple)",
            "default_field" : "content"
        }
    }
}

주의할 점: query_string은 invalid syntax에 대해 에러를 반환하므로 AND와 OR과 같은 query syntax를 지원해야되는 것이 아니라면 match를 사용하거나 좀 더 덜 엄격한 simple_query_string을 사용하는 것이 낫다.

 

4. Intervals

matching rules를 사용하여 쿼리한다. 여러개의 term들이 원하는 간격안에 존재하는지 쿼리한다.

아래의 쿼리는 "hot"과 "porridge"사이에 10단어 이상 간격이 없으면서 중간에 "salty"가 없어야 된다.

POST _search
{
  "query": {
    "intervals" : {
      "my_text" : {
        "match" : {
          "query" : "hot porridge",
          "max_gaps" : 10,
          "filter" : {
            "not_containing" : {
              "match" : {
                "query" : "salty"
              }
            }
          }
        }
      }
    }
  }
}

 

5. match_phrase

입력값을 analyze한다. 그리고 다음의 조건을 충족하는 document를 찾아서 반환한다.

- 모든 term들이 field에 존재해야한다.

- 모든 term들이 입력된 순서에 맞게 존재해야된다.

{ "foo":"I just said hello world" }
{ "foo":"Hello world" }
{ "foo":"World Hello" }

{
  "query": {
    "match_phrase": {
      "foo": "Hello World"
    }
  }
}
//1번째 2번째만 리턴된다. 3번째는 순서가 틀림

 

6. match_boolean_prefix

마지막 term을 제외한 모든 term은 term query에 사용된다. 마지막 term은 prefix query에 사용된다.

따라서 아래의 match_bool_prefix는 그 밑의 term과 prefix로 이루어진 query와 동일하다

GET /_search
{
    "query": {
        "match_bool_prefix" : {
            "message" : "quick brown f"
        }
    }
}

GET /_search
{
    "query": {
        "bool" : {
            "should": [
                { "term": { "message": "quick" }},
                { "term": { "message": "brown" }},
                { "prefix": { "message": "f"}}
            ]
        }
    }
}

match_phrase_prefix와 상당히 유사하지만 match_phrase_prefix는 입력값을 phrase로 보고 쭉 이어진 하나로 검색을 하는 반면, match_boolean_prefix는 term단위로 검색을 하기때문에 서로 떨어져 있어도 가능하고, 순서가 뒤섞여있어도 가능하다.

 

7. match_phrase_prefix

위에서 언급했던 것처럼 입력값을 하나의 뭉텅이로 검색한다 따라서:

     - quick brown fox (O)

     - two quick brown ferrets (O)

     - the fox is quick and brown (X)

 

8. multi_match

multi_match는 multi query를 바탕으로 여러 field를 동시에 쿼리할 수 있도록 한다.

GET /_search
{
  "query": {
    "multi_match" : {
      "query" : "this is a test",
      "fields" : [ "subject^3", "*_name" ] 
    }
  }
}

위의 코드처럼 subject 필드에 3배의 가중치를 줄 수 있으며 field이름에 * wildcard를 사용할 수 있다.

 

만약 field가 명시되어 있지 않다면 index.query.default_field로 설정된 field에서 검색하고, 이 default_field는 따로 명시하지 않았다면, index의 field는 term query를 수행할 수 있는 모든 field를 추출하여 수행한다.

 

multi_match가 어떻게 작동할지는 type 파라미터에 따라 결정된다.

 - best_fields: 여러개의 field들 중에서 입력값 단어들 중 가장 많은 단어를 가지고 있는 하나의 field의 점수를 사용

 - most_fields: 여러개의 field들의 점수를 산출한뒤 합산하고 field의 개수로 나눈 평균점수를 사용한다

 

 - phrase / phrase_prefix: best_fields와 똑같지만 match_phrase / match_phrase_prefix를 match대신 사용

 

 - cross fields: 여러개의 field가 동시에 만족되야할 경우(예: 성과 이름이 다른 field에 들어가있을때). query string을 individual term으로 analyze한 뒤에 마치 하나의 field를 검색하는 것처럼 모든 field를 살펴본다. 

(위의 best_field와 most_field와는 달리 어느 하나의 field에 모든 term이 존재하면 된다)

(주의: cross_fields에는 fuzziness가 사용될 수 없다)

 

tie_breaker: 점수가 산정되는 방식을 결정한다:

     - 0.0 : 모든 field 중 가장 높은 점수를 가진 field의 점수를 선택

     - 1.0 : 모든 field의 점수를 합함

     - 0.0 < n < 1.0: 가장 높은 field의 점수 + (n * 나머지 matching field 점수)

 

 

반응형
블로그 이미지

개발자_무형

,