Elasticsearch의 타자 오류를 어떻게 모호한 조회로 처리합니까


타자 오류는 자주 발생하는 일로 사용자의 체험을 줄일 수 있다. 다행히도, Elasticsearch는 모호한 검색을 통해 쉽게 처리할 수 있다.
만약 Elasticsearch로 고급 자동 완성 시스템을 구축하고 있다면, 타자 오류를 처리하는 것은 필수적이다.
만약 당신이 간단한 글을 만들고 싶다면, 당신은 나의 다른 문장인 'Create a Simple Autocomplete With Elasticsearch' 을 읽을 수 있습니다.

무엇이 모호 논리입니까


모호 논리는 일종의 수학 논리로 그 중에서 변수의 진가는 0에서 1 사이의 어떤 숫자도 될 수 있다.이것은 부울 논리와 달리 부울 논리는 진가 0이나 1만 있다.
Elasticsearch에서, 모호한 검색은 검색의 용어가 역색인의 용어와 완전히 일치하지 않아도 된다는 것을 의미한다.
Elasticsearch는 질의 사이의 거리를 계산하기 위해 Levenshtein Distance Algorithm을 사용합니다.

Levenshtein 거리 알고리즘을 사용하여 거리를 계산하는 방법


Levenshtein 거리 알고리즘으로 거리를 계산하는 것은 매우 쉽다.
너는 첫 번째 단어와 두 번째 단어를 하나씩 비교하기만 하면 된다.
문자가 다르면 단어 사이의 거리를 1로 늘릴 수 있다.
흔히 볼 수 있는 타자 오류 단어 “Gppgle”과 정확한 단어 “Google”의 거리를 어떻게 계산하는지 살펴보자.
elasticsearch 모호한 검색:Levenshtein 거리
우리가 Levenshtein 거리 알고리즘으로 “Gppgle”“Google” 사이의 거리를 계산한 후에 우리는 거리가 2라는 것을 알 수 있다.

신축성 검색 중의 모호한 검색


Elasticsearch의 입력 오류를 모호한 조회로 처리하는 것도 간단합니다.
먼저 타자 오류 단어 “Gppgle”의 예를 들자.
청원
curl --request POST \
  --url http://localhost:9200/fuzzy-query/_doc/_search \
  --header 'content-type: application/json' \
  --data '{
    "query": {
        "match" : {
            "text": {
                "query": "gppgle"
            }
        }
    }
}'

응수
{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 0,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  }
}

일반적인 일치하는 검색어를 사용할 때, Elasticsearch는 먼저 검색 “gppgle”을 분석한 다음에 Elasticsearch에 검색합니다.
역색인에서 유일한 용어는 구글인데 “gppgle”과 일치하지 않는다.따라서 Elasticsearch는 결과를 반환하지 않습니다.
이제 Elasticsearch의 모호한 일치 검색을 시도해 봅시다
청원
curl --request POST \
  --url http://localhost:9200/fuzzy-query/_doc/_search \
  --header 'content-type: application/json' \
  --data '{
    "query": {
        "match" : {
            "text": {
                "query": "gppgle",
                "fuzziness": "AUTO"
            }
        }
    }
}'

호응하다
{
  "took": 8,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.19178805,
    "hits": [
      {
        "_index": "fuzzy-query",
        "_type": "_doc",
        "_id": "w8YOCXUBHf9qB4Apc0Cz",
        "_score": 0.19178805,
        "_source": {
          "text": "google"
        }
      }
    ]
  }
}

보시다시피fuzzy에 대해 Elasticsearch가 응답을 되돌려줍니다.
우리는 이전 과정에서 “gppgle”“google”의 거리가 2라는 것을 알게 되었다.
검색에 우리는 숫자가 아닌 “fuzziness”:"AUTO"을 삽입했다.왜 그것이 일을 할 수 있습니까?
만약 우리가 “AUTO” 필드에서 “fuzziness” 값을 사용한다면, Elasticsearch는 어떤 모호한 거리가 적당한지 확인할 것이다.
6문자의 경우 기본적으로 Elasticsearch에서 두 개의 편집 거리를 허용합니다.“AUTO”의 모호도는 더 좋지만, 원한다면 정확한 숫자로 조정할 수 있다.
이제 “gppgle”“google”의 거리가 2라는 것을 정확한 숫자로 증명합시다.
gppgle과 구글과 모호1
청원
curl --request POST \
  --url 'http://localhost:9200/fuzzy-query/_doc/_search?explain=true' \
  --header 'content-type: application/json' \
  --data '{
    "query": {
        "match" : {
            "text": {
                "query": "gppgle",
                "fuzziness": "1"
            }
        }
    }
}'

응수
대답이 없다
gppgle과 구글과 모호2
청원
curl --request POST \
  --url http://localhost:9200/fuzzy-query/_doc/_search \
  --header 'content-type: application/json' \
  --data '{
    "query": {
        "match" : {
            "text": {
                "query": "gppgle",
                "fuzziness": "2"
            }
        }
    }
}'

응수
{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.19178805,
    "hits": [
      {
        "_index": "fuzzy-query",
        "_type": "_doc",
        "_id": "w8YOCXUBHf9qB4Apc0Cz",
        "_score": 0.19178805,
        "_source": {
          "text": "google"
        }
      }
    ]
  }
}

우리가 “fuzziness”:"1"을 사용할 때, Elasticsearch는 어떠한 결과도 되돌려주지 않습니다.
그러나 “fuzziness”:"2"에 대해 Elasticsearch는 문서 “google”을 되돌려주었다.
이것은 우리가 이전에 Levenshtein 거리 알고리즘으로 “gppgle”“google”의 거리를 계산한 결과 2라는 것을 증명한다.

Elasticsearch의 두 가지 모호한 검색


앞의 예시에서, 우리는 모호한 조회를 일치하는 조회의 매개 변수로 사용한다.
그러나 모호한 특징을 사용하는 또 다른 방법, 모호한 조회도 있다.
똑같은 것 같아!그렇다면 그들 사이에는 어떤 차이가 있을까?
계속하기 전에 analyzer에 대한 정보를 더 알고 싶으면 다른 글인 "Elasticsearch:Text vs.Keyword"를 읽으세요.

모호한 조회


모호한 조회의 작업 원리는 용어 조회와 유사하며, Elasticsearch의 조회를 분석하지 않고 역방향 색인을 검색하는 데 사용된다.
예를 들어, 문서 “Hong Kong”을 다시 인덱스합니다.
청원
curl --request POST \
  --url http://localhost:9200/fuzzy-query/_doc \
  --header 'content-type: application/json' \
  --data '{
    "text":"Hong Kong"
}'

응수
{
  "_index": "fuzzy-query",
  "_type": "_doc",
  "_id": "5sbKDXUBHf9qB4ApJUDr",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 1,
  "_primary_term": 1
}

Analyzer가 Elasticsearch의 Analyze API를 사용하여 생성한 용어를 살펴보겠습니다.
청원
curl --request POST \
  --url http://localhost:9200/_analyze \
  --header 'content-type: application/json' \
  --data '{
    "analyzer": "standard",
    "text": "Hong Kong"
}'

응수
{
  "tokens": [
    {
      "token": "hong",
      "start_offset": 0,
      "end_offset": 4,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "kong",
      "start_offset": 5,
      "end_offset": 9,
      "type": "<ALPHANUM>",
      "position": 1
    }
  ]
}

보시다시피 standard_analyzer은 두 가지 용어를 생성하는데 “hong”“kong”입니다.
만약 당신이 나의 또 다른 문장인 'Elasticsearch: Text vs. Keyword' 을 읽었다면, 만약 우리가 용어 조회를 사용하여 'Hong Kong' 을 검색한다면, 우리는 어떠한 결과도 얻지 못할 것이다.
청원
curl --request POST \
  --url http://localhost:9200/fuzzy-query/_doc/_search \
  --header 'content-type: application/json' \
  --data '{
    "query": {
        "fuzzy" : {
            "text": {
                "value": "Hpng Kpng",
                "fuzziness": "2"
            }
        }
    }
}'

응수
{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 0,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  }
}

Elasticsearch에서 “Hong Kong”과 편집 거리가 2보다 작은 단어가 하나도 없기 때문이다.
이제 “Hpng”을 사용하여 모호한 조회를 시도해 보겠습니다.
청원
curl --request POST \
  --url http://localhost:9200/fuzzy-query/_doc/_search \
  --header 'content-type: application/json' \
  --data '{
    "query": {
        "fuzzy" : {
            "text": {
                "value": "HPng",
                "fuzziness": "2"
            }
        }
    }
}'

응수
{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.60996956,
    "hits": [
      {
        "_index": "fuzzy-query",
        "_type": "_doc",
        "_id": "5sbKDXUBHf9qB4ApJUDr",
        "_score": 0.60996956,
        "_source": {
          "text": "Hong Kong"
        }
      }
    ]
  }
}

검색어의 용어 “Hpng”과 Elasticsearch의 용어 “hong”의 거리는 2이다.
검색의 용어와 역렬 색인 중의 용어는 대소문자를 구분하는데 거리'2'는 “Hp”“ho” 사이의 차이에서 나온다는 것을 기억해라.

모호한 매개 변수가 있는 일치 조회


모호한 파라미터가 있는 일치하는 검색이 모호한 검색보다 더 좋습니다.검색의 분석기는 검색을 역렬 인덱스로 검색하기 전에 분석할 것입니다.
모호한 검색 부분과 같은 검색을 시도해 봅시다.
청원
curl --request POST \
  --url http://localhost:9200/fuzzy-query/_doc/_search \
  --header 'content-type: application/json' \
  --data '{
    "query": {
        "match": {
            "text": {
                "query": "Hpng Kong",
                "fuzziness": 2
            }
        }
    }
}'


curl --request POST \
  --url http://localhost:9200/fuzzy-query/_doc/_search \
  --header 'content-type: application/json' \
  --data '{
    "query": {
        "match" : {
            "text": {
                "value": "HPng",
                "fuzziness": "2"
            }
        }
    }
}'

응수
{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.762462,
    "hits": [
      {
        "_index": "fuzzy-query",
        "_type": "_doc",
        "_id": "5sbKDXUBHf9qB4ApJUDr",
        "_score": 0.762462,
        "_source": {
          "text": "Hong Kong"
        }
      }
    ]
  }
}

예상한 바와 같이 두 개의 조회가 모두 하나의 결과를 되돌려 주었다.
첫 번째 조회는 “Hpng Kong”“hpng”“kong”으로 분석됐다.반전 색인에는 “hpng”“kong”이라는 두 용어가 동시에 존재한다.“hpng”“hong”이 일치하는 거리는 1이다.“kong”“kong”은 잘 어울린다.
일치하는 검색을 사용할 계획이라면, 주의해야 할 점은 검색의 모든 용어가 모호성을 허용한다는 것이다.
우리는 “hggg kggg”을 사용하여 조회를 시도할 수 있으며 편집 거리는 4이고 “Hong Kong”을 사용하여 조회를 진행할 수 있다.
청원
curl --request POST \
  --url http://localhost:9200/fuzzy-query/_doc/_search \
  --header 'content-type: application/json' \
  --data '{
    "query": {
        "match": {
            "text": {
                "query": "hggg kggg",
                "fuzziness": "2"
            }
        }
    }
}'

응수
{
    "_index": "fuzzy-query",
    "_type": "_doc",
    "_id": "5sbKDXUBHf9qB4ApJUDr",
    "_score": 1.2330425,
    "_source": {
        "text": "Hong Kong"
    }
}

보시다시피 Elasticsearch가 결과를 되돌려줍니다.
분석기가 조회 “fuzziness”:2“hggg kggg”“hggg”으로 분석했기 때문이다.
Elasticsearch에서 “kggg”“hggg”의 편집 거리는 각각 2에서 “kggg”, “hong”이다.

Elasticsearch에서 모호한 조회 조정


사용자의 용례에 맞게 모호한 조회를 조정할 수 있습니다.
이 절에서, 나는 우리가 조회에서 변경할 수 있는 매개 변수를 소개할 것이다.

모호성


모호성은 모호 조회의 핵심이다.
우리가 이 매개 변수에 전달하는 값은 허용되는 최대 거리이다.
우리는 두 가지 유형의 값, 정확한 최대 거리의 정수와 “kong”을 전달할 수 있다.“AUTO” 값은 검색의 모호성을 동적으로 허용합니다.
우리는 “AUTO” 값의 두 파라미터를 조정하여 “AUTO”에 쓸 수 있다.용어 길이가 하한치보다 낮으면 질의는 흐림도를 0으로 설정합니다.용어 길이가 낮은 값과 높은 값 사이에 있으면 조회는 모호성을 1로 설정합니다.마지막으로 용어의 길이가 높은 값보다 크면 조회는 모호도를 2로 설정합니다.
Elasticsearch는 하한값과 상한값이 확정되지 않은 경우 3과 6을 기본값으로 사용합니다.
"Elasticsearch의 모호한 검색을 사용하면 타자 오류를 처리할 수 있습니다."라는 문서의 예시를 사용합니다.
우리는 앞에서 설명한 자동 메커니즘을 증명하기 위해 몇 가지 조회를 시도할 수 있다.
  • “AUTO:[low],[high]”: 편집 거리 “tp”의 거리.
  • “to”: 편집 거리 “Fyzzy”의 거리.
  • “Fuzzy”:2 편집 거리 “Fyzyy”의 거리.
  • “Fuzzy”:2 편집 거리 “Elastissearcc”의 거리.
  • “Fuzzy”:3 편집 거리 “Elestissearcc”의 거리.
  • 질의가 완료되면 다음과 같은 결과가 생성됩니다.
  • “Fuzzy”
  • “Fyzzy”
  • 이러한 질의에는 다음 사항이 적용되지 않습니다.
  • “Elastissearcc”
  • “tp”
  • “Fyzyy”
  • 자리를 바꾸다

    “Elestissearcc”은 두 개의 인접 문자 (ab->ba) 의 위치를 1거리로 계산할 수 있도록 합니다.
    예를 들어 만약에 우리가 transpositions을true로 설정한다면 transpositions을 사용하여 조회를 하면 결과를 얻을 수 있다.
    그러나 false로 설정하면 Elasticsearch는 결과를 얻지 못합니다.
    청원
    {
      "query": {
        "fuzzy": {
          "text": {
            "value": "leasticsearcc",
            "fuzziness": "AUTO",
            "transpositions": true
          }
        }
      }
    }
    
    
    응수
    {
        "_index": "fuzzy-query",
        "_type": "_doc",
        "_id": "AsawDnUBHf9qB4ApNUFh",
        "_score": 0.5491282,
        "_source": {
            "text": "Fuzzy Query in Elasticsearch allows you to handle typos"
        }
    }
    
    
    Elasticsearch는 “leasticsearcc”을 기본값true로 설정합니다.
    이 설정을 검색어와 일치하도록 설정할 수 없습니다.일치 조회는 항상 transpositions을 1거리로 계산합니다.

    최대 확장

    transpositions은 질의에서 얻은 최대 결과를 결정합니다.max_expansions을 1로 설정하고 Elasticsearch 중 2개의 문서가 검색에 적합하면 Elasticsearch는 1만 되돌려줍니다.max_expansions은 조각 레벨에 적용됩니다.따라서 Elasticsearch에 많은 조각이 있다면 max_expansions을 1로 설정하더라도 조회는 더 많은 결과를 되돌릴 수 있습니다.max_expansion의 기본값은 50입니다.

    접두사 길이

    max_expansions은 모호한 검색에서 고려하지 않은 접두사 문자수입니다.
    예를 들어 만약에 우리가 prefix_length을 1로 설정한다면 prefix_length을 조회하면 아무런 결과도 얻지 못할 것이다.
    접두사 길이 설정은 기본적으로 0입니다.

    다시 쓰다


    결과의 평점을 변경하려면 “llasticsearch” 매개 변수를 변경할 수 있습니다.
    Elasticsearch documentation에서 rewrite 매개 변수에 대한 더 많은 정보를 찾을 수 있습니다.

    결론


    Elasticsearch에서 타자 오류를 처리하는 것은 매우 간단하여 사용자 체험을 개선할 수 있다.
    입력 오류를 처리하는 가장 간단한 방법은 일치하는 검색에 rewrite을 추가하는 것이다.
    검색을 최적화하려면 몇 가지 파라미터를 변경할 수 있는데 그 중에서 가장 중요한 파라미터는 “fuzziness”:"AUTO"이다.
    끝까지 읽어주셔서 감사합니다!
    Elasticsearch에 관한 다른 글들을 계속 주목해 주세요!

    좋은 웹페이지 즐겨찾기