>source

엘라스틱 7.15.0을 사용하고 있습니다. 공백이 있거나 없는 우선 순위로 검색을 구성하고 싶습니다. 무슨 뜻인가요?

쿼리 -"surf coff"

  1. "surf coff"를 포함하거나 시작하는 레code를 보고 싶습니다. -(SURF COFFEE, SURF CAFFETERIA, SURFCOFFEE MAN)
  2. 레code가 "surf"를 포함하거나 시작하는 경우 -(SURF, SURF LOVE, ENDLESS SURF)
  3. 기록이 "coff"를 포함하거나 시작하는 경우 -(LOVE COFFEE, COFFEE MAN)

쿼리 -"surfoff"

  1. (SURF COFFEE, SURF CAFFETERIA, SURFCOFFEE MAN)만 포함하거나 "surfoff"로 시작하는 레code를 보고 싶습니다.

필터가 있는 분석기를 만들었습니다.

  • 소문자
  • word_delimiter_graph
  • 싱글
  • 엣지 n 그램
  • 공백의 패턴 교체

{
   "settings":{
       "index": {
            "max_shingle_diff" : 9,
            "max_ngram_diff": 9
       },
      "analysis":{
         "analyzer":{
            "word_join_analyzer":{
               "tokenizer":"standard",
               "filter":[
                  "lowercase",
                  "word_delimiter_graph",
                  "my_shingle",
                  "my_edge_ngram",
                  "my_char_filter"
               ]
            }
         },
         "filter":{
            "my_shingle":{
               "type":"shingle",
               "min_shingle_size": 2,
                "max_shingle_size": 10
            },
            "my_edge_ngram": {
                "type": "edge_ngram",
                "min_gram": 2,
                "max_gram": 10,
                "token_chars": ["letter", "digit"]
            },
            "my_char_filter": {
                "type": "pattern_replace",
                "pattern": " ",
                "replacement": ""
            }
         }
      }
   }
}

텍스트= "SURF COFFEE"를 분석했을 때 이 결과를 얻었습니다.

{
    "tokens": [
        {
            "token": "su",
            "start_offset": 0,
            "end_offset": 4,
            "type": "<ALPHANUM>",
            "position": 0
        },
        {
            "token": "sur",
            "start_offset": 0,
            "end_offset": 4,
            "type": "<ALPHANUM>",
            "position": 0
        },
        {
            "token": "surf",
            "start_offset": 0,
            "end_offset": 4,
            "type": "<ALPHANUM>",
            "position": 0
        },
        {
            "token": "su",
            "start_offset": 0,
            "end_offset": 11,
            "type": "shingle",
            "position": 0,
            "positionLength": 2
        },
        {
            "token": "sur",
            "start_offset": 0,
            "end_offset": 11,
            "type": "shingle",
            "position": 0,
            "positionLength": 2
        },
        {
            "token": "surf",
            "start_offset": 0,
            "end_offset": 11,
            "type": "shingle",
            "position": 0,
            "positionLength": 2
        },
        {
            "token": "surf",
            "start_offset": 0,
            "end_offset": 11,
            "type": "shingle",
            "position": 0,
            "positionLength": 2
        },
        {
            "token": "surfc",
            "start_offset": 0,
            "end_offset": 11,
            "type": "shingle",
            "position": 0,
            "positionLength": 2
        },
        {
            "token": "surfco",
            "start_offset": 0,
            "end_offset": 11,
            "type": "shingle",
            "position": 0,
            "positionLength": 2
        },
        {
            "token": "surfcof",
            "start_offset": 0,
            "end_offset": 11,
            "type": "shingle",
            "position": 0,
            "positionLength": 2
        },
        {
            "token": "surfcoff",
            "start_offset": 0,
            "end_offset": 11,
            "type": "shingle",
            "position": 0,
            "positionLength": 2
        },
        {
            "token": "surfcoffe",
            "start_offset": 0,
            "end_offset": 11,
            "type": "shingle",
            "position": 0,
            "positionLength": 2
        },
        {
            "token": "co",
            "start_offset": 5,
            "end_offset": 11,
            "type": "<ALPHANUM>",
            "position": 1
        },
        {
            "token": "cof",
            "start_offset": 5,
            "end_offset": 11,
            "type": "<ALPHANUM>",
            "position": 1
        },
        {
            "token": "coff",
            "start_offset": 5,
            "end_offset": 11,
            "type": "<ALPHANUM>",
            "position": 1
        },
        {
            "token": "coffe",
            "start_offset": 5,
            "end_offset": 11,
            "type": "<ALPHANUM>",
            "position": 1
        },
        {
            "token": "coffee",
            "start_offset": 5,
            "end_offset": 11,
            "type": "<ALPHANUM>",
            "position": 1
        }
    ]
}

보다시피 "surfcoff" 토큰이 있습니다.

검색을 어떻게 구성해야 합니까?

나는 bool이 다음과 쿼리해야 하는 접근 방식을 결합하려고 시도했습니다. query_string, match_phrase_prefix, match_prefix 등.

그러나 그들 중 누구도 올바른 결과를 내지 못했습니다.

도와주시겠습니까?

내 쿼리는 어떻게 작성해야 합니까? 아니면 다른 분석기 필터를 사용해 봐야 합니다.

예시 쿼리

{
  "query": {
    "bool": {
      "should": [
        {
          "query_string": {
                "query": "surf coff",
                "default_field": "text",
                "default_operator": "AND"
            }
        },
        {
          "query_string": {
                "query": "surf",
                "default_field": "text"
            }
        },
        {
          "query_string": {
                "query": "coff",
                "default_field": "text"
            }
        }
      ]
    }
  }
}

또는 이 쿼리

{
  "query": {
    "bool": {
      "should": [
        {
          "query_string": {
                "query": "(surf coff) OR (surf) OR (coff)",
                "default_field": "text"
            }
        }
      ]
    }
  }
}

또는 이 쿼리

{
  "query": {
    "bool": {
      "should": [
        {
          "query_string": {
                "query": "((surf AND coff)^3 OR (surf)^2 OR (coff)^1)",
                "default_field": "text"
            }
        }
      ]
    }
  }
}

또는

{
  "query": {
    "match_bool_prefix" : {
      "text" : "surf coff"
    }
  }
}

주다

  1. 절대 혼자하지 않는 서핑 커피
  2. 코노수르 콜차과 코노수르
  3. 선라이즈 콘차 토로 선라이즈 300일
  4. 선커피
  5. 서핑 커피 홍보 ....

하지만 이상합니다. 제가 뭔가를 잘못 이해하고 있는 것 같습니다.

  • 답변 # 1

    마침내 해결됨

    "filter":[
                      "lowercase",
                      "word_delimiter_graph",
                      "my_shingle",
                       "my_edge_ngram",
                      "my_char_filter"
                   ]
    

    문제는 search_analyzer에 있었습니다. 문서에서 " 자동 완성을 위해 토크나이저를 사용하거나 검색 시 동의어를 사용할 때와 같이 검색 시 다른 분석기를 사용하는 것이 합리적일 수 있습니다."라고 문서에서 말했기 때문입니다.

    그래서 내 텍스트 필드에 표준 search_analyzer를 추가했습니다.

    "text": { "type": "text", "analyzer": "word_join_analyzer", "search_analyzer": "standard" }
    

    검색어:

    {
      "query": {
        "bool": {
          "should": [
            {
              "query_string": {
                    "query": "surf coff",
                    "default_field": "text"
                }
            }
          ]
        }
      }
    }
    

  • 답변 # 2

    {
      "query": {
        "bool": {
          "should": [
            {
              "query_string": {
                    "query": "(surf* AND coff*)^3 OR (surf*)^2 OR (coff*)^1",
                    "default_field": "text"
                }
            }
          ]
        }
      }
    }
    

    {
       "settings":{
           "index": {
                "max_shingle_diff" : 9,
                "max_ngram_diff": 9
           },
          "analysis":{
             "analyzer":{
                "word_join_analyzer":{
                   "tokenizer":"standard",
                   "filter":[
                      "lowercase",
                      "word_delimiter_graph",
                       "my_shingle",
                       "my_char_filter"
                   ]
                }
             },
             "filter":{
                "my_shingle":{
                   "type":"shingle",
                   "min_shingle_size": 2,
                    "max_shingle_size": 10
                },
                "my_char_filter": {
                    "type": "pattern_replace",
                    "pattern": " ",
                    "replacement": ""
                }
             }
          }
       }
    }
    

    edge-n-gram을 제거하고 우선 순위가 있는 Wilcard 쿼리를 추가하면 내 질문이 해결되었습니다. 그러나 나는 여전히 edge n gram이 작동하지 않는 이유를 이해하지 못합니다.

  • 이전 docusignapi : Power Automate에서 DocuSign의 시작점은?
  • 다음 java : PO 메커니즘에 대한 클래스의 개체 관리