Azure Cognitive Search의 전체 텍스트 검색Full text search in Azure Cognitive Search

이 문서는 Azure Cognitive Search에서 Lucene 전체 텍스트 검색이 작동 하는 방식을 심층적으로 이해 해야 하는 개발자를 위한 것입니다.This article is for developers who need a deeper understanding of how Lucene full text search works in Azure Cognitive Search. 텍스트 쿼리의 경우 Azure Cognitive Search는 대부분의 시나리오에서 예상된 결과를 원활하게 제공하지만, 가끔은 "예상과 다른" 결과를 얻기도 합니다.For text queries, Azure Cognitive Search will seamlessly deliver expected results in most scenarios, but occasionally you might get a result that seems "off" somehow. 이러한 상황에서는 Lucene 쿼리 실행의 네 단계(쿼리 구문 분석, 어휘 분석, 문서 일치, 점수 매기기)에 대한 배경 지식을 갖고 있으면 쿼리 매개 변수의 특정 변경 내용 또는 원하는 결과를 제공하는 인덱스 구성을 식별하는 데 도움이 될 수 있습니다.In these situations, having a background in the four stages of Lucene query execution (query parsing, lexical analysis, document matching, scoring) can help you identify specific changes to query parameters or index configuration that will deliver the desired outcome.

참고

Azure Cognitive Search는 전체 텍스트 검색에 Lucene를 사용 하지만 Lucene 통합은 완전 하지 않습니다.Azure Cognitive Search uses Lucene for full text search, but Lucene integration is not exhaustive. Azure Cognitive Search에 중요 한 시나리오를 사용할 수 있도록 Lucene 기능을 선택적으로 노출 하 고 확장 합니다.We selectively expose and extend Lucene functionality to enable the scenarios important to Azure Cognitive Search.

아키텍처 개요 및 다이어그램Architecture overview and diagram

전체 텍스트 검색 쿼리의 처리는 쿼리 텍스트를 구문 분석하여 검색 용어를 추출하는 작업부터 시작합니다.Processing a full text search query starts with parsing the query text to extract search terms. 검색 엔진은 인덱스를 사용하여 일치하는 용어가 포함된 문서를 검색합니다.The search engine uses an index to retrieve documents with matching terms. 잠재적 일치 항목으로 간주할 수 있는 항목의 범위를 넓히기 위해 때때로 개별 쿼리 용어를 새로운 형식으로 분류하고 재구성하기도 합니다.Individual query terms are sometimes broken down and reconstituted into new forms to cast a broader net over what could be considered as a potential match. 그런 다음 각 개별 일치 문서에 할당된 관련성 점수를 기준으로 결과 집합을 정렬합니다.A result set is then sorted by a relevance score assigned to each individual matching document. 순위 목록 맨 위에 있는 항목은 호출 애플리케이션으로 반환됩니다.Those at the top of the ranked list are returned to the calling application.

다시 정리하면, 쿼리 실행은 다음과 같은 네 단계로 구성됩니다.Restated, query execution has four stages:

  1. 쿼리 구문 분석Query parsing
  2. 어휘 분석Lexical analysis
  3. 문서 검색Document retrieval
  4. 점수 매기기Scoring

아래 다이어그램은 검색 요청을 처리하는 데 사용되는 구성 요소를 보여 줍니다.The diagram below illustrates the components used to process a search request.

Azure Cognitive Search의 Lucene 쿼리 아키텍처 다이어그램

핵심 구성 요소Key components 기능 설명Functional description
쿼리 파서Query parsers 쿼리 연산자에서 쿼리 용어를 분리하고 검색 엔진에 전송할 쿼리 구조(쿼리 트리)를 만듭니다.Separate query terms from query operators and create the query structure (a query tree) to be sent to the search engine.
분석기Analyzers 쿼리 용어에 대한 어휘 분석을 수행합니다.Perform lexical analysis on query terms. 이 프로세스에는 쿼리 용어의 변환, 제거 또는 확장이 포함될 수 있습니다.This process can involve transforming, removing, or expanding of query terms.
IndexIndex 인덱싱된 문서에서 추출된 검색 가능한 용어를 저장하고 정리하는 데 사용되는 효율적인 데이터 구조입니다.An efficient data structure used to store and organize searchable terms extracted from indexed documents.
검색 엔진Search engine 반전된 인덱스의 내용을 기준으로 일치하는 문서를 검색하고 점수를 매깁니다.Retrieves and scores matching documents based on the contents of the inverted index.

검색 요청 분석Anatomy of a search request

검색 요청은 결과 집합에 반환할 완전한 규격입니다.A search request is a complete specification of what should be returned in a result set. 가장 간단한 형태는 어떠한 조건도 없는 빈 쿼리입니다.In simplest form, it is an empty query with no criteria of any kind. 보다 현실적인 예로는 매개 변수 및 몇몇 쿼리 용어가 있습니다. 경우에 따라 검색 범위가 특정 필드로 지정되거나 필터 식과 정렬 규칙을 사용할 수도 있습니다.A more realistic example includes parameters, several query terms, perhaps scoped to certain fields, with possibly a filter expression and ordering rules.

다음 예제는 REST API를 사용 하 여 Azure Cognitive Search에 보낼 수 있는 검색 요청입니다.The following example is a search request you might send to Azure Cognitive Search using the REST API.

POST /indexes/hotels/docs/search?api-version=2020-06-30
{
    "search": "Spacious, air-condition* +\"Ocean view\"",
    "searchFields": "description, title",
    "searchMode": "any",
    "filter": "price ge 60 and price lt 300",
    "orderby": "geo.distance(location, geography'POINT(-159.476235 22.227659)')", 
    "queryType": "full" 
}

이 요청의 경우 검색 엔진이 다음 작업을 수행합니다.For this request, the search engine does the following:

  1. 가격이 $60 이상 $300 미만인 문서를 필터링합니다.Filters out documents where the price is at least $60 and less than $300.
  2. 쿼리를 실행합니다.Executes the query. 이 예제의 검색 쿼리는 다음과 같은 구와 용어로 구성되어 있습니다. "Spacious, air-condition* +\"Ocean view\""(일반적으로는 사용자가 문장 부호를 입력하지 않지만, 이 예에서는 분석기가 문장 부호를 어떻게 처리하는지 설명하기 위해 문장 부호를 포함함).In this example, the search query consists of phrases and terms: "Spacious, air-condition* +\"Ocean view\"" (users typically don't enter punctuation, but including it in the example allows us to explain how analyzers handle it). 이 쿼리에서 검색 엔진은 "Ocean view"가 포함된 문서를 찾기 위해 searchFields에 지정된 설명 및 제목 필드를 검색하고, 추가적으로 "spacious" 용어 또는 접두사 "air-condition"으로 시작하는 용어를 검색합니다.For this query, the search engine scans the description and title fields specified in searchFields for documents that contain "Ocean view", and additionally on the term "spacious", or on terms that start with the prefix "air-condition". searchMode 매개 변수는 용어가 명시적으로 필요하지 않은 경우(+)에 일부 일치(기본값) 또는 전체 일치에 사용됩니다.The searchMode parameter is used to match on any term (default) or all of them, for cases where a term is not explicitly required (+).
  3. 호텔 검색 결과 집합을 특정 지리적 위치에 가까운 순서대로 정렬한 후 호출 애플리케이션으로 반환합니다.Orders the resulting set of hotels by proximity to a given geography location, and then returned to the calling application.

이 문서의 대부분은 검색 쿼리 를 처리 하는 방법에 대 한 것입니다 "Spacious, air-condition* +\"Ocean view\"" .The majority of this article is about processing of the search query: "Spacious, air-condition* +\"Ocean view\"". 필터링 및 정렬은 본 문서에서 다루지 않습니다.Filtering and ordering are out of scope. 자세한 내용은 검색 API 참조 문서를 참조하세요.For more information, see the Search API reference documentation.

1단계: 쿼리 구문 분석Stage 1: Query parsing

앞서 설명했듯이, 쿼리 문자열은 요청의 첫 번째 줄입니다.As noted, the query string is the first line of the request:

 "search": "Spacious, air-condition* +\"Ocean view\"", 

쿼리 파서는 검색 용어에서 예제의 *+ 같은 연산자를 분리하고, 검색 쿼리를 지원되는 유형의 하위 쿼리 로 분해합니다.The query parser separates operators (such as * and + in the example) from search terms, and deconstructs the search query into subqueries of a supported type:

  • 독립 용어(예: spacious)에 대한 용어 쿼리term query for standalone terms (like spacious)
  • 따옴표가 붙은 용어(예: ocean view)에 대한 구 쿼리phrase query for quoted terms (like ocean view)
  • 뒤에 * 접두사 연산자가 붙는 용어(예: air-condition)에 대한 접두사 쿼리prefix query for terms followed by a prefix operator * (like air-condition)

지원되는 쿼리 유형의 전체 목록은 Lucene 쿼리 구문을 참조하세요.For a full list of supported query types see Lucene query syntax

하위 쿼리와 관련된 연산자는 문서를 일치 항목으로 간주하려면 쿼리를 "반드시 만족"해야 하는지 아니면 "만족하면 더 좋은지" 여부를 결정합니다.Operators associated with a subquery determine whether the query "must be" or "should be" satisfied in order for a document to be considered a match. 예를 들어 +"Ocean view"+ 연산자가 붙었기 때문에 "반드시" 만족되어야 합니다.For example, +"Ocean view" is "must" due to the + operator.

쿼리 파서는 하위 쿼리를 검색 엔진으로 전달하는 쿼리 트리(쿼리를 나타내는 내부 구조)로 재구성합니다.The query parser restructures the subqueries into a query tree (an internal structure representing the query) it passes on to the search engine. 쿼리 구문 분석의 첫 번째 단계에서는 쿼리 트리가 다음과 같습니다.In the first stage of query parsing, the query tree looks like this.

부울 쿼리 searchmode any

지원되는 파서: 단순(simple) 및 전체(full) LuceneSupported parsers: Simple and Full Lucene

Azure Cognitive Search는 (기본값) 및의 두 가지 쿼리 언어를 노출 simple full 합니다.Azure Cognitive Search exposes two different query languages, simple (default) and full. 사용자는 검색 요청에서 queryType 매개 변수를 설정함으로써 쿼리 파서에 어떤 쿼리 언어를 사용하여 연산자와 구문을 해석해야 하는지 알려줍니다.By setting the queryType parameter with your search request, you tell the query parser which query language you choose so that it knows how to interpret the operators and syntax. 단순 쿼리 언어는 직관적이고 견고하며, 종종 클라이언트 측 처리 없이 사용자 입력을 있는 그대로 해석하는 데 적합합니다.The Simple query language is intuitive and robust, often suitable to interpret user input as-is without client-side processing. 웹 검색 엔진과 비슷한 쿼리 연산자를 지원합니다.It supports query operators familiar from web search engines. queryType=full로 설정하면 사용할 수 있는 전체 Lucene 쿼리 언어는 와일드카드, 퍼지, regex, 필드 범위가 지정된 쿼리 등의 추가 연산자 및 쿼리 유형에 대한 지원을 추가하여 기본값인 단순 쿼리 언어를 확장합니다.The Full Lucene query language, which you get by setting queryType=full, extends the default Simple query language by adding support for more operators and query types like wildcard, fuzzy, regex, and field-scoped queries. 예를 들어 단순 쿼리 구문에서 전송되는 정규식은 식이 아닌 쿼리 문자열로 해석됩니다.For example, a regular expression sent in Simple query syntax would be interpreted as a query string and not an expression. 이 문서의 요청 예제에서는 전체 Lucene 쿼리 언어를 사용합니다.The example request in this article uses the Full Lucene query language.

searchMode가 파서에 미치는 영향Impact of searchMode on the parser

구문 분석에 영향을 주는 또 다른 검색 요청은 searchMode 매개 변수입니다.Another search request parameter that affects parsing is the searchMode parameter. 이 매개 변수는 부울 쿼리의 기본 연산자인 일부(기본값) 또는 전체를 제어합니다.It controls the default operator for Boolean queries: any (default) or all.

기본값인 searchMode=any로 설정된 경우 spacious와 air-condition 사이의 공백 구분 기호는 OR(||)이며, 샘플 쿼리 텍스트는 다음과 같습니다.When searchMode=any, which is the default, the space delimiter between spacious and air-condition is OR (||), making the sample query text equivalent to:

Spacious,||air-condition*+"Ocean view" 

+"Ocean view"+ 같은 명시적 연산자는 부울 쿼리 구조에서 모호하지 않습니다(용어가 반드시 일치해야 함).Explicit operators, such as + in +"Ocean view", are unambiguous in boolean query construction (the term must match). 나머지 용어 spacious와 air-condition을 해석하는 방법은 덜 명확합니다.Less obvious is how to interpret the remaining terms: spacious and air-condition. 검색 엔진이 ocean view 그리고 spacious 그리고 air-condition과 일치하는 항목을 찾아야 합니까?Should the search engine find matches on ocean view and spacious and air-condition? 아니면 ocean view와 나머지 두 용어 중 하나 를 찾아야 합니까?Or should it find ocean view plus either one of the remaining terms?

기본적으로(searchMode=any) 검색 엔진은 보다 광범위한 해석을 가정합니다.By default (searchMode=any), the search engine assumes the broader interpretation. "or" 구문을 반영하여 두 필드 중 하나가 일치 해야 합니다.Either field should be matched, reflecting "or" semantics. 앞에서 보여드린 두 개의 "should" 연산이 사용된 초기 쿼리 트리는 기본값을 표시합니다.The initial query tree illustrated previously, with the two "should" operations, shows the default.

만약 searchMode=all로 설정한다면 어떨까요?Suppose that we now set searchMode=all. 이 경우 공간이 "and" 연산으로 해석됩니다.In this case, the space is interpreted as an "and" operation. 나머지 두 용어가 모두 문서에 있어야만 일치 항목으로 인정됩니다.Each of the remaining terms must both be present in the document to qualify as a match. 결과 샘플 쿼리는 다음과 같이 해석됩니다.The resulting sample query would be interpreted as follows:

+Spacious,+air-condition*+"Ocean view"

이 쿼리의 수정된 쿼리 트리는 다음과 같으며, 세 하위 쿼리가 교차하는 부분이 바로 일치하는 문서입니다.A modified query tree for this query would be as follows, where a matching document is the intersection of all three subqueries:

부울 쿼리 searchmode all

참고

searchMode=all 대신 searchMode=any를 선택하는 것은 대표 쿼리를 실행하여 도착할 수 있는 최선의 결정입니다.Choosing searchMode=any over searchMode=all is a decision best arrived at by running representative queries. 연산자를 포함할 가능성(문서 저장소를 검색할 때 일반적)이 높은 사용자는 searchMode=all이 부울 쿼리 구문에 알릴 때 좀 더 직관적인 결과를 얻을 수 있습니다.Users who are likely to include operators (common when searching document stores) might find results more intuitive if searchMode=all informs boolean query constructs. searchMode 및 연산자 간의 상호 작용에 대한 자세한 내용은 단순 쿼리 구문을 참조하세요.For more about the interplay between searchMode and operators, see Simple query syntax.

2단계: 어휘 분석Stage 2: Lexical analysis

어휘 분석기는 쿼리 트리가 구조화된 후 용어 쿼리구 쿼리 를 처리합니다.Lexical analyzers process term queries and phrase queries after the query tree is structured. 분석기는 파서에서 제공한 텍스트 입력을 수락하고, 해당 텍스트를 처리한 후 토큰화된 용어를 다시 보내서 쿼리 트리와 통합합니다.An analyzer accepts the text inputs given to it by the parser, processes the text, and then sends back tokenized terms to be incorporated into the query tree.

어휘 분석의 가장 일반적인 형태는 지정된 언어와 관련된 규칙을 기반으로 쿼리 용어를 변환하는 언어 분석 입니다.The most common form of lexical analysis is linguistic analysis which transforms query terms based on rules specific to a given language:

  • 쿼리 용어를 단어의 루트 형식으로 줄이기Reducing a query term to the root form of a word
  • 필수적이지 않은 단어(영어의 "the" 또는 "and" 같은 중지 단어) 제거Removing non-essential words (stopwords, such as "the" or "and" in English)
  • 복합 단어를 구성 요소 부분으로 분리Breaking a composite word into component parts
  • 대문자 단어를 소문자로 변환Lower casing an upper case word

이 모든 작업은 사용자가 제공한 텍스트 입력과 인덱스에 저장된 용어 사이의 차이점을 없애는 경향이 있습니다.All of these operations tend to erase differences between the text input provided by the user and the terms stored in the index. 이러한 작업은 텍스트 처리에서 그치지 않으며 언어 자체에 대한 심도 있는 지식을 필요로 합니다.Such operations go beyond text processing and require in-depth knowledge of the language itself. 이 언어 인식 계층을 추가 하기 위해 Azure Cognitive Search는 Lucene 및 Microsoft의 긴 언어 분석기 목록을 지원 합니다.To add this layer of linguistic awareness, Azure Cognitive Search supports a long list of language analyzers from both Lucene and Microsoft.

참고

분석 요구 사항은 시나리오에 따라 최소한의 수준부터 복잡한 수준까지 달라질 수 있습니다.Analysis requirements can range from minimal to elaborate depending on your scenario. 미리 정의된 분석기 중 하나를 선택하거나 사용자 지정 분석기를 직접 만들어서 어휘 분석의 복잡성을 제어할 수 있습니다.You can control complexity of lexical analysis by the selecting one of the predefined analyzers or by creating your own custom analyzer. 분석기는 필드 정의의 일부로 지정되며 분석기의 범위는 검색 가능한 필드입니다.Analyzers are scoped to searchable fields and are specified as part of a field definition. 따라서 필드별로 어휘 분석을 다르게 할 수 있습니다.This allows you to vary lexical analysis on a per-field basis. 분석기를 지정하지 않으면 표준 Lucene 분석기가 사용됩니다.Unspecified, the standard Lucene analyzer is used.

우리 예제에서는 분석에 앞서 초기 쿼리 트리에 "Spacious,"라는 용어가 있습니다. 대문자 "S"와 쿼리 파서가 쿼리 용어의 일부로 해석하는 쉼표(쉼표는 쿼리 언어 연산자로 간주되지 않음)가 사용되었습니다.In our example, prior to analysis, the initial query tree has the term "Spacious," with an uppercase "S" and a comma that the query parser interprets as a part of the query term (a comma is not considered a query language operator).

기본 분석기는 이 용어를 처리할 때 "ocean view" 및 "spacious"를 소문자로 변환하고 쉼표 문자를 제거합니다.When the default analyzer processes the term, it will lowercase "ocean view" and "spacious", and remove the comma character. 수정된 쿼리 트리는 다음과 같습니다.The modified query tree will look as follows:

분석된 용어를 사용한 부울 쿼리

분석기 동작 테스트Testing analyzer behaviors

분석 API를 사용하여 분석기의 동작을 테스트할 수 있습니다.The behavior of an analyzer can be tested using the Analyze API. 분석할 텍스트를 입력하여 주어진 분석기가 어떤 용어를 생성하는지 살펴봅니다.Provide the text you want to analyze to see what terms given analyzer will generate. 예를 들어 표준 분석기가 "air-condition"이라는 텍스트를 어떻게 처리하는지 살펴보려면 다음 요청을 실행하면 됩니다.For example, to see how the standard analyzer would process the text "air-condition", you can issue the following request:

{
    "text": "air-condition",
    "analyzer": "standard"
}

표준 분석기는 입력 텍스트를 다음과 같은 두 토큰으로 분류하고, 위치(구 일치에 사용)뿐 아니라 시작 및 종료 오프셋(적중 항목 강조 표시에 사용) 같은 특성을 사용하여 주석을 답니다.The standard analyzer breaks the input text into the following two tokens, annotating them with attributes like start and end offsets (used for hit highlighting) as well as their position (used for phrase matching):

{
  "tokens": [
    {
      "token": "air",
      "startOffset": 0,
      "endOffset": 3,
      "position": 0
    },
    {
      "token": "condition",
      "startOffset": 4,
      "endOffset": 13,
      "position": 1
    }
  ]
}

어휘 분석의 예외Exceptions to lexical analysis

어휘 분석은 완전한 용어가 필요한 쿼리 유형, 즉 용어 쿼리 또는 구 쿼리에만 적용됩니다.Lexical analysis applies only to query types that require complete terms – either a term query or a phrase query. 불완전한 용어가 사용된 쿼리, 다시 말해서 접두사 쿼리, 와일드 카드 쿼리, regex 쿼리 또는 유사 항목 쿼리에는 적용되지 않습니다.It doesn’t apply to query types with incomplete terms – prefix query, wildcard query, regex query – or to a fuzzy query. 우리 예제의 air-condition*이라는 용어가 사용된 접두사 쿼리를 포함하여 이러한 쿼리 유형은 분석 단계를 건너뛰고 쿼리 트리에 직접 추가됩니다.Those query types, including the prefix query with term air-condition* in our example, are added directly to the query tree, bypassing the analysis stage. 이러한 유형의 쿼리 용어에 수행되는 유일한 변환 작업은 소문자 변환입니다.The only transformation performed on query terms of those types is lowercasing.

3단계: 문서 검색Stage 3: Document retrieval

문서 검색이란 인덱스에서 일치하는 용어가 포함된 문서를 찾는 것을 말합니다.Document retrieval refers to finding documents with matching terms in the index. 이 단계는 예를 통해 설명하는 것이 가장 빠릅니다.This stage is understood best through an example. 다음과 같은 간단한 스키마를 가진 호텔 인덱스로 시작해 보겠습니다.Let's start with a hotels index having the following simple schema:

{
    "name": "hotels",
    "fields": [
        { "name": "id", "type": "Edm.String", "key": true, "searchable": false },
        { "name": "title", "type": "Edm.String", "searchable": true },
        { "name": "description", "type": "Edm.String", "searchable": true }
    ] 
} 

또한 이 인덱스에 다음과 같은 네 개 문서가 포함되어 있다고 가정하겠습니다.Further assume that this index contains the following four documents:

{
    "value": [
        {
            "id": "1",
            "title": "Hotel Atman",
            "description": "Spacious rooms, ocean view, walking distance to the beach."
        },
        {
            "id": "2",
            "title": "Beach Resort",
            "description": "Located on the north shore of the island of Kauaʻi. Ocean view."
        },
        {
            "id": "3",
            "title": "Playa Hotel",
            "description": "Comfortable, air-conditioned rooms with ocean view."
        },
        {
            "id": "4",
            "title": "Ocean Retreat",
            "description": "Quiet and secluded"
        }
    ]
}

용어 인덱싱 방식How terms are indexed

인덱싱에 대한 몇 가지 기본 사항을 파악하면 검색을 이해하는 데 도움이 됩니다.To understand retrieval, it helps to know a few basics about indexing. 스토리지 단위는 반전된 인덱스이며, 검색 가능한 필드당 하나씩 있습니다.The unit of storage is an inverted index, one for each searchable field. 반전된 인덱스 내에는 모든 문서의 모든 정렬된 용어 목록이 있습니다.Within an inverted index is a sorted list of all terms from all documents. 각 용어는 아래 예제처럼 각각 발생하는 문서 목록에 매핑됩니다.Each term maps to the list of documents in which it occurs, as evident in the example below.

반전된 인덱스에 용어를 생성하기 위해 검색 엔진은 쿼리 처리 중 발생하는 동작과 비슷하게 문서 내용에 대한 어휘 분석을 수행합니다.To produce the terms in an inverted index, the search engine performs lexical analysis over the content of documents, similar to what happens during query processing:

  1. 텍스트 입력 은 분석기 구성에 따라 분석기로 전달되고, 소문자로 변환되고, 문장 부호가 제거됩니다.Text inputs are passed to an analyzer, lower-cased, stripped of punctuation, and so forth, depending on the analyzer configuration.
  2. 토큰 은 어휘 분석의 출력입니다.Tokens are the output of lexical analysis.
  3. 용어 는 인덱스에 추가됩니다.Terms are added to the index.

쿼리 용어가 인덱스 내 용어와 좀 더 비슷하게 보이도록 검색 작업과 인덱싱 작업에 같은 분석기를 사용하는 것이 일반적이지만 필수는 아닙니다.It's common, but not required, to use the same analyzers for search and indexing operations so that query terms look more like terms inside the index.

참고

Azure Cognitive Search를 사용 하면 추가 indexAnalyzer 및 필드 매개 변수를 통해 인덱싱 및 검색에 대해 다른 분석기를 지정할 수 있습니다 searchAnalyzer .Azure Cognitive Search lets you specify different analyzers for indexing and search via additional indexAnalyzer and searchAnalyzer field parameters. 분석기를 지정하지 않으면 analyzer 속성을 통해 설정된 분석기가 인덱싱과 검색에 모두 사용됩니다.If unspecified, the analyzer set with the analyzer property is used for both indexing and searching.

예제 문서의 반전된 인덱스Inverted index for example documents

예제로 돌아가서, 제목 필드의 경우 반전된 인덱스는 다음과 같습니다.Returning to our example, for the title field, the inverted index looks like this:

용어Term 문서 목록Document list
atmanatman 11
beachbeach 22
hotelhotel 1, 31, 3
oceanocean 44
playaplaya 33
resortresort 33
retreatretreat 44

제목 필드에서는 오직 hotel 만 1, 3 문서에 표시됩니다.In the title field, only hotel shows up in two documents: 1, 3.

설명 필드의 경우 인덱스는 다음과 같습니다.For the description field, the index is as follows:

용어Term 문서 목록Document list
airair 33
and 44
beachbeach 11
conditionedconditioned 33
comfortablecomfortable 33
distancedistance 11
islandisland 22
kauaʻikauaʻi 22
locatedlocated 22
northnorth 22
oceanocean 1, 2, 31, 2, 3
ofof 22
Onon 22
quietquiet 44
roomsrooms 1, 31, 3
secludedsecluded 44
shoreshore 22
spaciousspacious 11
thethe 1, 21, 2
toto 11
view 1, 2, 31, 2, 3
walkingwalking 11
다음과 같이 바꿉니다.with 33

쿼리 용어를 인덱싱된 용어와 연결Matching query terms against indexed terms

위의 반전된 인덱스를 전제로, 샘플 쿼리로 돌아가서 예제 쿼리와 일치하는 문서를 어떻게 찾아내는지 살펴보겠습니다.Given the inverted indices above, let’s return to the sample query and see how matching documents are found for our example query. 최종 쿼리 트리는 다음과 같다고 했습니다.Recall that the final query tree looks like this:

분석된 용어를 사용한 부울 쿼리

쿼리가 실행되는 동안, 검색 가능한 필드에 대해 개별 쿼리가 독립적으로 실행됩니다.During query execution, individual queries are executed against the searchable fields independently.

  • TermQuery "spacious"는 문서 1(Hotel Atman)과 일치합니다.The TermQuery, "spacious", matches document 1 (Hotel Atman).

  • PrefixQuery "air-condition*"은 일치하는 문서가 없습니다.The PrefixQuery, "air-condition*", doesn't match any documents.

    이는 종종 개발자를 혼란스럽게 만드는 동작입니다.This is a behavior that sometimes confuses developers. air-conditioned라는 용어가 문서에 있기는 하지만 이 용어는 기본 분석기에서 두 개 용어로 분할됩니다.Although the term air-conditioned exists in the document, it is split into two terms by the default analyzer. 앞에서 부분 용어를 포함한 접두사 쿼리가 분석되지 않은 것을 떠올려 보세요.Recall that prefix queries, which contain partial terms, are not analyzed. 따라서 접두사 "air-condition"을 포함하는 용어는 반전된 인덱스에서 조회되지만 찾을 수 없었습니다.Therefore terms with prefix "air-condition" are looked up in the inverted index and not found.

  • PhraseQuery "ocean view"는 용어 "ocean"과 "view"를 조회하며 원래 문서에서 용어의 근접도를 확인합니다.The PhraseQuery, "ocean view", looks up the terms "ocean" and "view" and checks the proximity of terms in the original document. 문서 1, 2, 3은 설명 필드가 이 쿼리와 일치합니다.Documents 1, 2 and 3 match this query in the description field. 문서 4는 제목에 용어 ocean이 있지만 일치 항목으로 간주되지 않습니다. 쿼리에서 찾는 것이 개별 단어가 아닌 "ocean view"라는 구이기 때문입니다.Notice document 4 has the term ocean in the title but isn’t considered a match, as we're looking for the "ocean view" phrase rather than individual words.

참고

검색 쿼리는 searchFields 예제 검색 요청에 설명 된 대로 매개 변수를 사용 하 여 설정 된 필드를 제한 하지 않는 한 Azure Cognitive Search 인덱스의 모든 검색 가능 필드에 대해 독립적으로 실행 됩니다.A search query is executed independently against all searchable fields in the Azure Cognitive Search index unless you limit the fields set with the searchFields parameter, as illustrated in the example search request. 선택한 필드 중 아무 필드와 일치하는 문서가 반환됩니다.Documents that match in any of the selected fields are returned.

전체적으로 볼 때, 예제의 쿼리와 일치하는 문서는 1, 2, 3입니다.On the whole, for the query in question, the documents that match are 1, 2, 3.

4단계: 점수 매기기Stage 4: Scoring

검색 결과 집합의 모든 문서에 관련성 점수가 할당됩니다.Every document in a search result set is assigned a relevance score. 관련성 점수의 기능은 검색 쿼리의 표현에 따라 사용자 질문에 가장 잘 대답한 문서에 더 높은 순위를 매기는 것입니다.The function of the relevance score is to rank higher those documents that best answer a user question as expressed by the search query. 점수는 일치하는 용어의 통계 속성에 따라 계산됩니다.The score is computed based on statistical properties of terms that matched. 점수 매기기 공식의 핵심은 TF/IDF(term frequency-inverse document frequency)입니다.At the core of the scoring formula is TF/IDF (term frequency-inverse document frequency). 드문 용어와 일반적인 용어가 포함된 쿼리에서, TF/IDF는 드문 용어가 포함된 결과에 더 높은 순위를 부여합니다.In queries containing rare and common terms, TF/IDF promotes results containing the rare term. 예를 들어 모든 Wikipedia 문서가 포함된 가상의 인덱스에서 the president 쿼리와 일치하는 문서의 경우 president 와 일치하는 문서는 the 와 일치하는 문서보다 관련성이 높은 것으로 간주됩니다.For example, in a hypothetical index with all Wikipedia articles, from documents that matched the query the president, documents matching on president are considered more relevant than documents matching on the.

점수 매기기 예제Scoring example

앞에서 예제 쿼리와 일치한 세 문서를 떠올려 보세요.Recall the three documents that matched our example query:

search=Spacious, air-condition* +"Ocean view"  
{
  "value": [
    {
      "@search.score": 0.25610128,
      "id": "1",
      "title": "Hotel Atman",
      "description": "Spacious rooms, ocean view, walking distance to the beach."
    },
    {
      "@search.score": 0.08951007,
      "id": "3",
      "title": "Playa Hotel",
      "description": "Comfortable, air-conditioned rooms with ocean view."
    },
    {
      "@search.score": 0.05967338,
      "id": "2",
      "title": "Ocean Resort",
      "description": "Located on a cliff on the north shore of the island of Kauai. Ocean view."
    }
  ]
}

문서 1이 쿼리와 가장 정확하게 일치했습니다. spacious 라는 용어와 ocean view 라는 필수 구가 설명 필드에서 모두 발생했기 때문입니다.Document 1 matched the query best because both the term spacious and the required phrase ocean view occur in the description field. 그 다음 두 문서는 ocean view 라는 구만 일치합니다.The next two documents match only the phrase ocean view. 문서 2와 3이 동일한 방식으로 쿼리와 일치하는데 관련성 점수는 서로 다르다는 점에 놀라실 수도 있습니다.It might be surprising that the relevance score for document 2 and 3 is different even though they matched the query in the same way. 이는 점수 매기기 공식에 TF/IDF 외에도 여러 구성 요소가 더 있기 때문입니다.It's because the scoring formula has more components than just TF/IDF. 이 예에서는 문서 3에 약간 더 높은 점수가 할당되었는데, 설명이 좀 더 짧기 때문입니다.In this case, document 3 was assigned a slightly higher score because its description is shorter. 필드 길이 및 기타 요소가 관련성 점수에 미치는 영향에 대해 자세히 알아보려면 Lucene의 실제 점수 매기기 공식을 살펴보세요.Learn about Lucene's Practical Scoring Formula to understand how field length and other factors can influence the relevance score.

일부 쿼리 유형(와일드카드, 접두사, regex)은 전체적인 문서 점수에 항상 상수 점수를 부여합니다.Some query types (wildcard, prefix, regex) always contribute a constant score to the overall document score. 따라서 쿼리 확장을 통해 검색된 일치 항목이 결과에는 포함되지만 순위에는 영향을 주지 않습니다.This allows matches found through query expansion to be included in the results, but without affecting the ranking.

이것이 왜 중요한지 예제를 통해 살펴보겠습니다.An example illustrates why this matters. 접두사 검색을 포함한 와일드카드 검색은 기본적으로 모호할 수밖에 없습니다. 왜냐하면 그 입력이 수많은 다른 용어와 일치할 가능성이 있는 부분 문자열이기 때문입니다(예를 들어 "tour*"를 입력하면 “tours”, “tourettes”, “tourmaline”이 전부 일치 항목으로 검색됨).Wildcard searches, including prefix searches, are ambiguous by definition because the input is a partial string with potential matches on a very large number of disparate terms (consider an input of "tour*", with matches found on “tours”, “tourettes”, and “tourmaline”). 이러한 결과의 특성을 감안할 때, 어떤 용어가 더 중요한지 합리적으로 유추할 방법이 없습니다.Given the nature of these results, there is no way to reasonably infer which terms are more valuable than others. 이러한 이유로 와일드카드, 접두사, regex 쿼리 유형의 결과에 대한 점수를 매길 때에는 용어 빈도를 무시합니다.For this reason, we ignore term frequencies when scoring results in queries of types wildcard, prefix and regex. 부분 용어와 완전한 용어가 포함된 다중 파트 검색 요청에서 부분 입력의 결과는 예상치 않은 일치 항목 가능성을 방지하기 위해 상수 점수와 통합됩니다.In a multi-part search request that includes partial and complete terms, results from the partial input are incorporated with a constant score to avoid bias towards potentially unexpected matches.

점수 조정Score tuning

Azure Cognitive Search에서 관련성 점수를 조정 하는 방법에는 두 가지가 있습니다.There are two ways to tune relevance scores in Azure Cognitive Search:

  1. 점수 매기기 프로필 은 규칙 집합을 기준으로 순위가 지정된 결과 목록에서 문서를 승격합니다.Scoring profiles promote documents in the ranked list of results based on a set of rules. 이 문서의 예제에서는 제목 필드와 일치하는 문서가 설명 필드와 일치하는 문서보다 관련성이 높은 것으로 간주할 수 있습니다.In our example, we could consider documents that matched in the title field more relevant than documents that matched in the description field. 뿐만 아니라 만약 인덱스에 각 호텔의 가격 필드가 있다면 가격이 낮은 문서를 승격할 수 있습니다.Additionally, if our index had a price field for each hotel, we could promote documents with lower price. 검색 인덱스에 점수 매기기 프로필 추가에 대해 자세히 알아보세요.Learn more how to add Scoring Profiles to a search index.
  2. 용어 상승(전체 Lucene 쿼리 구문에만 사용 가능)은 쿼리 트리의 어떤 부분에도 적용할 수 있는 ^ 상승 연산자를 제공합니다.Term boosting (available only in the Full Lucene query syntax) provides a boosting operator ^ that can be applied to any part of the query tree. 이 예제에서는 접두사 공기 조건을 검색 하는 대신 * 정확한 용어 공기 조건 또는 접두사를 검색할 수 있지만, 정확한 용어에서 일치 하는 문서는 쿼리 라는 용어에 상승 (* 공기 조건 ^ 2 | |)을 적용 하 여 더 높은 순위를 갖습니다. 공기 조건 * *.In our example, instead of searching on the prefix air-condition*, one could search for either the exact term air-condition or the prefix, but documents that match on the exact term are ranked higher by applying boost to the term query: *air-condition^2||air-condition**. 용어 상승에 대해 자세히 알아보세요.Learn more about term boosting.

분산된 인덱스에 점수 매기기Scoring in a distributed index

Azure Cognitive Search의 모든 인덱스는 자동으로 여러 분할 분할 되므로 서비스 규모를 확장 하거나 축소 하는 동안 여러 노드 간에 인덱스를 신속 하 게 배포할 수 있습니다.All indexes in Azure Cognitive Search are automatically split into multiple shards, allowing us to quickly distribute the index among multiple nodes during service scale up or scale down. 검색 요청이 실행될 때 검색 요청은 각 분할 영역에 대해 독립적으로 실행됩니다.When a search request is issued, it’s issued against each shard independently. 그런 다음 각 분할 영역의 결과가 점수를 기준으로(다른 정렬 기준이 정의되지 않은 경우) 병합되고 정렬됩니다.The results from each shard are then merged and ordered by score (if no other ordering is defined). 점수 매기기 함수는 분할 영역 전체가 아닌 해당 분할 영역 내부의 모든 문서에서 반전 문서 빈도보다 쿼리 용어 빈도에 가중치를 부여한다는 것을 기억해야 합니다.It is important to know that the scoring function weights query term frequency against its inverse document frequency in all documents within the shard, not across all shards!

즉, 같은 문서라도 서로 다른 분할 영역에 상주할 경우 관련성 점수가 다를 수 있습니다.This means a relevance score could be different for identical documents if they reside on different shards. 다행스럽게도 이러한 차이는 인덱스의 문서 수가 증가하면 용어가 보다 균등하게 배포되기 때문에 사라지는 경향이 있습니다.Fortunately, such differences tend to disappear as the number of documents in the index grows due to more even term distribution. 특정 문서가 어떤 분할 영역에 배치되는지 추정하는 것은 불가능합니다.It’s not possible to assume on which shard any given document will be placed. 그러나 문서 키가 변경되지 않는다고 가정할 때 항상 같은 분할 영역에 할당됩니다.However, assuming a document key doesn't change, it will always be assigned to the same shard.

순서 안정성이 중요한 경우 일반적으로 문서 점수는 문서를 정렬하는 최선의 특성이 아닙니다.In general, document score is not the best attribute for ordering documents if order stability is important. 예를 들어 점수가 같은 두 개의 문서가 있을 때, 같은 쿼리를 또 다시 실행하면 어떤 문서가 먼저 표시되는지 보장할 수 없습니다.For example, given two documents with an identical score, there is no guarantee which one appears first in subsequent runs of the same query. 문서 점수는 결과 집합의 다른 문서와 비교한 일반적인 문서 관련성만 제공합니다.Document score should only give a general sense of document relevance relative to other documents in the results set.

결론Conclusion

인터넷 검색 엔진의 성공으로 프라이빗 데이터에 대한 전체 텍스트 검색의 기대가 높아졌습니다.The success of internet search engines has raised expectations for full text search over private data. 이제 우리는 거의 모든 종류의 검색 환경에서 용어의 맞춤법이 틀리거나 불완전하더라도 엔진이 사람의 의도를 이해할 수 있을 것으로 기대합니다.For almost any kind of search experience, we now expect the engine to understand our intent, even when terms are misspelled or incomplete. 실제로 지정하지 않은 거의 비슷한 용어 또는 동의어 기반의 일치 항목까지도 기대할 수 있습니다.We might even expect matches based on near equivalent terms or synonyms that we never actually specified.

기술적인 측면에서 전체 텍스트 검색은 매우 복잡합니다. 쿼리 용어를 제거하고, 확장하고, 변환하여 관련 결과를 제공하는 정교한 언어 분석과 체계적인 처리 방법이 필요합니다.From a technical standpoint, full text search is highly complex, requiring sophisticated linguistic analysis and a systematic approach to processing in ways that distill, expand, and transform query terms to deliver a relevant result. 내재된 복잡성을 고려할 때 쿼리 결과에 영향을 줄 수 있는 수많은 요소가 있습니다.Given the inherent complexities, there are a lot of factors that can affect the outcome of a query. 이러한 이유로 전체 텍스트 검색의 역학을 이해하는 데 시간을 투자하면 예상치 않은 결과를 작업할 때 확실한 이점이 있습니다.For this reason, investing the time to understand the mechanics of full text search offers tangible benefits when trying to work through unexpected results.

이 문서에서는 Azure Cognitive Search 컨텍스트에서 전체 텍스트 검색을 탐색 했습니다.This article explored full text search in the context of Azure Cognitive Search. 일반적인 쿼리 문제의 잠재적 원인과 해결책을 찾는 데 충분한 배경 지식을 익히셨기를 바랍니다.We hope it gives you sufficient background to recognize potential causes and resolutions for addressing common query problems.

다음 단계Next steps

추가 정보See also

문서 검색 REST APISearch Documents REST API

단순 쿼리 구문Simple query syntax

Full Lucene 쿼리 구문Full Lucene query syntax

검색 결과 처리Handle search results