빠른 시작: REST API를 사용하여 PowerShell에서 검색 인덱스 만들기

이 Azure AI Search 빠른 시작에서는 PowerShell 및 Azure AI Search REST API를 사용하여 검색 인덱스를 만들고, 로드하고 , 쿼리하는 방법을 알아봅니다. 이 문서에서는 PowerShell 명령을 대화형으로 실행하는 방법에 대해 설명합니다. 또는 동일한 작업을 수행하는 PowerShell 스크립트를 다운로드하여 실행할 수 있습니다.

Azure 구독이 아직 없는 경우 시작하기 전에 체험 계정을 만듭니다.

필수 조건

이 빠른 시작에는 다음 서비스 및 도구가 필요합니다.

검색 서비스 키 및 URL 복사

이 빠른 시작에서 REST 호출에는 모든 요청에 대한 서비스 URL 및 액세스 키가 포함됩니다. 검색 서비스는 둘 다로 만들어지므로 구독에 Azure AI Search를 추가한 경우 다음 단계에 따라 필요한 정보를 가져옵니다.

  1. Azure Portal에 로그인합니다. 검색 서비스 개요 페이지에서 URL을 가져옵니다. 엔드포인트의 예는 다음과 같습니다. https://mydemo.search.windows.net

  2. 설정> 키를 선택한 다음 서비스에 대한 모든 권한에 대한 관리 키를 가져옵니다. 1오버를 롤오버해야 하는 경우 비즈니스 연속성을 위해 두 개의 교환 가능한 관리 키가 제공됩니다. 개체 추가, 수정 및 삭제 요청 시 기본 또는 보조 키를 사용할 수 있습니다.

    HTTP 엔드포인트 및 액세스 키 가져오기를 보여 주는 스크린샷

모든 요청에는 서비스로 전송된 모든 요청에 API 키가 필요합니다. 유효한 키를 보유하면 요청을 보내는 애플리케이션과 요청을 처리하는 서비스 간에 요청별로 트러스트가 설정됩니다.

  1. PowerShell에서 콘텐츠 형식 및 API 키를 저장할 개체를 만듭니 $headers 다. 관리자 API 키(YOUR-ADMIN-API-KEY)를 검색 서비스에 유효한 키로 바꿉니다. 세션 기간 동안 이 헤더를 한 번만 설정하면 되지만 모든 요청에 추가합니다.

    $headers = @{
    'api-key' = '<YOUR-ADMIN-API-KEY>'
    'Content-Type' = 'application/json' 
    'Accept' = 'application/json' }
    
  2. $url 서비스의 인덱스 컬렉션을 지정하는 개체를 만듭니다. 서비스 이름(YOUR-SEARCH-SERVICE-NAME)을 유효한 검색 서비스로 바꿉니다.

    $url = "https://<YOUR-SEARCH-SERVICE-NAME>.search.windows.net/indexes?api-version=2023-11-01&`$select=name"
    
  3. 실행 Invoke-RestMethod 하여 서비스에 GET 요청을 보내고 연결을 확인합니다. 서비스에서 다시 전송된 응답을 볼 수 있도록 추가 ConvertTo-Json 합니다.

    Invoke-RestMethod -Uri $url -Headers $headers | ConvertTo-Json
    

    서비스가 비어 있고 인덱스가 없는 경우 결과는 다음 예제와 비슷합니다. 그렇지 않으면 인덱스 정의의 JSON 표현이 표시됩니다.

    {
        "@odata.context":  "https://mydemo.search.windows.net/$metadata#indexes",
        "value":  [
    
                ]
    }
    

인덱스 만들기

포털을 사용하지 않는 한 데이터를 로드하려면 먼저 인덱스가 서비스에 있어야 합니다. 이 단계에서는 인덱스를 정의하고 서비스로 푸시합니다. 이 단계에는 인덱스 만들기 REST API가 사용됩니다.

인덱스의 필수 요소에는 name 및 fields 컬렉션이 포함됩니다. fields 컬렉션은 문서의 구조를 정의합니다. 각 필드에는 사용 방법을 결정하는 이름, 형식 및 특성이 있습니다(예: 검색 결과에서 전체 텍스트 검색 가능, 필터링 가능 또는 검색 가능 여부). 인덱스 내에서 Edm.String 형식의 필드 중 하나는 문서 ID에 대한 key로 지정해야 합니다.

이 인덱스의 이름은 hotels-quickstart 다음 코드에 표시되는 필드 정의가 있습니다. 다른 연습 문서에서 사용되는 더 큰 호텔 인덱 스의 하위 집합입니다. 간단히 하기 위해 이 빠른 시작에서 필드 정의가 잘립니다.

  1. 이 예제를 PowerShell에 붙여넣어 인덱스 스키마가 포함된 개체를 만듭니 $body 다.

    $body = @"
    {
        "name": "hotels-quickstart",  
        "fields": [
            {"name": "HotelId", "type": "Edm.String", "key": true, "filterable": true},
            {"name": "HotelName", "type": "Edm.String", "searchable": true, "filterable": false, "sortable": true, "facetable": false},
            {"name": "Description", "type": "Edm.String", "searchable": true, "filterable": false, "sortable": false, "facetable": false, "analyzer": "en.lucene"},
            {"name": "Category", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true},
            {"name": "Tags", "type": "Collection(Edm.String)", "searchable": true, "filterable": true, "sortable": false, "facetable": true},
            {"name": "ParkingIncluded", "type": "Edm.Boolean", "filterable": true, "sortable": true, "facetable": true},
            {"name": "LastRenovationDate", "type": "Edm.DateTimeOffset", "filterable": true, "sortable": true, "facetable": true},
            {"name": "Rating", "type": "Edm.Double", "filterable": true, "sortable": true, "facetable": true},
            {"name": "Address", "type": "Edm.ComplexType", 
            "fields": [
            {"name": "StreetAddress", "type": "Edm.String", "filterable": false, "sortable": false, "facetable": false, "searchable": true},
            {"name": "City", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true},
            {"name": "StateProvince", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true},
            {"name": "PostalCode", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true},
            {"name": "Country", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true}
            ]
         }
      ]
    }
    "@
    
  2. URI를 서비스 및 인덱스의 인덱스 컬렉션으로 hotels-quickstart 설정합니다.

    $url = "https://<YOUR-SEARCH-SERVICE>.search.windows.net/indexes/hotels-quickstart?api-version=2023-11-01"
    
  3. $headers$body 사용하여 명령을 $url실행하고 서비스에서 인덱스 만들기

    Invoke-RestMethod -Uri $url -Headers $headers -Method Put -Body $body | ConvertTo-Json
    

    결과는 간결하게 하기 위해 처음 두 필드만 표시하는 이 예제와 유사해야 합니다.

    {
        "@odata.context":  "https://mydemo.search.windows.net/$metadata#indexes/$entity",
        "@odata.etag":  "\"0x8D6EDE28CFEABDA\"",
        "name":  "hotels-quickstart",
        "defaultScoringProfile":  null,
        "fields":  [
                    {
                        "name":  "HotelId",
                        "type":  "Edm.String",
                        "searchable":  true,
                        "filterable":  true,
                        "retrievable":  true,
                        "sortable":  true,
                        "facetable":  true,
                        "key":  true,
                        "indexAnalyzer":  null,
                        "searchAnalyzer":  null,
                        "analyzer":  null,
                        "synonymMaps":  ""
                    },
                    {
                        "name":  "HotelName",
                        "type":  "Edm.String",
                        "searchable":  true,
                        "filterable":  false,
                        "retrievable":  true,
                        "sortable":  true,
                        "facetable":  false,
                        "key":  false,
                        "indexAnalyzer":  null,
                        "searchAnalyzer":  null,
                        "analyzer":  null,
                        "synonymMaps":  ""
                    },
                    . . .
        ]
    }
    

확인을 위해 포털에서 인덱스 목록을 검사 수도 있습니다.

문서 로드

문서를 푸시하려면 인덱스의 URL 엔드포인트에 대한 HTTP POST 요청을 사용합니다. 이 작업의 REST API는 문서 추가, 업데이트 또는 삭제입니다.

  1. 이 예제를 PowerShell에 붙여넣어 업로드할 문서가 포함된 개체를 만듭니 $body 다.

    이 요청에는 두 개의 전체 레코드와 하나의 부분 레코드가 포함됩니다. 부분 레코드는 불완전한 문서를 업로드할 수 있음을 보여 줍니다. @search.action 매개 변수는 인덱싱을 수행하는 방법을 지정합니다. 유효한 값은 upload, merge, mergeOrUploaddelete을 포함합니다. 동작은 mergeOrUpload 새 문서를 hotelId = 3 만들거나 이미 있는 경우 내용을 업데이트합니다.

    $body = @"
    {
        "value": [
        {
        "@search.action": "upload",
        "HotelId": "1",
        "HotelName": "Secret Point Motel",
        "Description": "The hotel is ideally located on the main commercial artery of the city in the heart of New York. A few minutes away is Time's Square and the historic centre of the city, as well as other places of interest that make New York one of America's most attractive and cosmopolitan cities.",
        "Category": "Boutique",
        "Tags": [ "pool", "air conditioning", "concierge" ],
        "ParkingIncluded": false,
        "LastRenovationDate": "1970-01-18T00:00:00Z",
        "Rating": 3.60,
        "Address": 
            {
            "StreetAddress": "677 5th Ave",
            "City": "New York",
            "StateProvince": "NY",
            "PostalCode": "10022",
            "Country": "USA"
            } 
        },
        {
        "@search.action": "upload",
        "HotelId": "2",
        "HotelName": "Twin Dome Motel",
        "Description": "The hotel is situated in a  nineteenth century plaza, which has been expanded and renovated to the highest architectural standards to create a modern, functional and first-class hotel in which art and unique historical elements coexist with the most modern comforts.",
        "Category": "Boutique",
        "Tags": [ "pool", "free wifi", "concierge" ],
        "ParkingIncluded": false,
        "LastRenovationDate": "1979-02-18T00:00:00Z",
        "Rating": 3.60,
        "Address": 
            {
            "StreetAddress": "140 University Town Center Dr",
            "City": "Sarasota",
            "StateProvince": "FL",
            "PostalCode": "34243",
            "Country": "USA"
            } 
        },
        {
        "@search.action": "upload",
        "HotelId": "3",
        "HotelName": "Triple Landscape Hotel",
        "Description": "The Hotel stands out for its gastronomic excellence under the management of William Dough, who advises on and oversees all of the Hotel’s restaurant services.",
        "Category": "Resort and Spa",
        "Tags": [ "air conditioning", "bar", "continental breakfast" ],
        "ParkingIncluded": true,
        "LastRenovationDate": "2015-09-20T00:00:00Z",
        "Rating": 4.80,
        "Address": 
            {
            "StreetAddress": "3393 Peachtree Rd",
            "City": "Atlanta",
            "StateProvince": "GA",
            "PostalCode": "30326",
            "Country": "USA"
            } 
        },
        {
        "@search.action": "upload",
        "HotelId": "4",
        "HotelName": "Sublime Cliff Hotel",
        "Description": "Sublime Cliff Hotel is located in the heart of the historic center of Sublime in an extremely vibrant and lively area within short walking distance to the sites and landmarks of the city and is surrounded by the extraordinary beauty of churches, buildings, shops and monuments. Sublime Cliff is part of a lovingly restored 1800 palace.",
        "Category": "Boutique",
        "Tags": [ "concierge", "view", "24-hour front desk service" ],
        "ParkingIncluded": true,
        "LastRenovationDate": "1960-02-06T00:00:00Z",
        "Rating": 4.60,
        "Address": 
            {
            "StreetAddress": "7400 San Pedro Ave",
            "City": "San Antonio",
            "StateProvince": "TX",
            "PostalCode": "78216",
            "Country": "USA"
            }
        }
    ]
    }
    "@
    
  2. 엔드포인트를 docs 컬렉션으로 hotels-quickstart 설정하고 인덱스 작업(indexes/hotels-quickstart/docs/index)을 포함합니다.

    $url = "https://<YOUR-SEARCH-SERVICE>.search.windows.net/indexes/hotels-quickstart/docs/index?api-version=2023-11-01"
    
  3. $headers$body 사용하여 명령을 $url실행하고 인덱스로 문서를 로드합니다hotels-quickstart.

    Invoke-RestMethod -Uri $url -Headers $headers -Method Post -Body $body | ConvertTo-Json
    

    결과는 다음 예제와 비슷합니다. 201 상태 코드가 표시됩니다.

    {
        "@odata.context":  "https://mydemo.search.windows.net/indexes(\u0027hotels-quickstart\u0027)/$metadata#Collection(Microsoft.Azure.Search.V2019_05_06.IndexResult)",
        "value":  [
                    {
                        "key":  "1",
                        "status":  true,
                        "errorMessage":  null,
                        "statusCode":  201
                    },
                    {
                        "key":  "2",
                        "status":  true,
                        "errorMessage":  null,
                        "statusCode":  201
                    },
                    {
                        "key":  "3",
                        "status":  true,
                        "errorMessage":  null,
                        "statusCode":  201
                    },
                    {
                        "key":  "4",
                        "status":  true,
                        "errorMessage":  null,
                        "statusCode":  201
                    }
                ]
    }
    

인덱스 검색

이 단계에서는 문서 검색 API를 사용하여 인덱싱을 쿼리하는 방법을 보여줍니다.

검색 $urls시 작은따옴표를 사용해야 합니다. 쿼리 문자열에는 문자가 포함 $ 되며 전체 문자열이 작은따옴표로 묶인 경우 이스케이프할 필요가 없습니다.

  1. 엔드포인트를 docs 컬렉션으로 hotels-quickstart 설정하고 쿼리 문자열에 search 전달할 매개 변수를 추가합니다.

    이 문자열은 임의의 문서의 순위가 지정되지 않은 목록(검색 점수 = 1.0)을 반환하여 빈 검색(search=*)을 실행합니다. 기본적으로 Azure AI 검색은 한 번에 50개의 일치 항목을 반환합니다. 구조적으로 이 쿼리는 전체 문서 구조와 값을 반환합니다. 결과에 있는 모든 문서 수를 가져오기 위해 추가 $count=true 합니다.

    $url = 'https://<YOUR-SEARCH-SERVICE>.search.windows.net/indexes/hotels-quickstart/docs?api-version=2023-11-01&search=*&$count=true'
    
  2. 명령을 실행하여 서비스로 보냅니 $url 다.

    Invoke-RestMethod -Uri $url -Headers $headers | ConvertTo-Json
    

    결과는 다음 출력과 비슷합니다.

    {
    "@odata.context":  "https://mydemo.search.windows.net/indexes(\u0027hotels-quickstart\u0027)/$metadata#docs(*)",
    "@odata.count":  4,
    "value":  [
                  {
                      "@search.score":  0.1547872,
                      "HotelId":  "2",
                      "HotelName":  "Twin Dome Motel",
                      "Description":  "The hotel is situated in a  nineteenth century plaza, which has been expanded and renovated to the highest architectural standards to create a modern, functional and first-class hotel in which art and unique historical elements coexist with the most modern comforts.",
                      "Category":  "Boutique",
                      "Tags":  "pool free wifi concierge",
                      "ParkingIncluded":  false,
                      "LastRenovationDate":  "1979-02-18T00:00:00Z",
                      "Rating":  3.6,
                      "Address":  "@{StreetAddress=140 University Town Center Dr; City=Sarasota; StateProvince=FL; PostalCode=34243; Country=USA}"
                  },
                  {
                      "@search.score":  0.009068266,
                      "HotelId":  "3",
                      "HotelName":  "Triple Landscape Hotel",
                      "Description":  "The Hotel stands out for its gastronomic excellence under the management of William Dough, who advises on and oversees all of the Hotel\u0027s restaurant services.",
                      "Category":  "Resort and Spa",
                      "Tags":  "air conditioning bar continental breakfast",
                      "ParkingIncluded":  true,
                      "LastRenovationDate":  "2015-09-20T00:00:00Z",
                      "Rating":  4.8,
                      "Address":  "@{StreetAddress=3393 Peachtree Rd; City=Atlanta; StateProvince=GA; PostalCode=30326; Country=USA}"
                  },
                . . .
        ]
    }
    

구문을 이해하기 위해 몇 가지 다른 쿼리 예제를 시도해봅니다. 문자열 검색, 축 $filter 자 쿼리를 수행하고, 결과 집합을 제한하고, 검색 범위를 특정 필드로 지정하는 등의 작업을 수행할 수 있습니다.

# Query example 1
# Search the entire index for the terms 'restaurant' and 'wifi'
# Return only the HotelName, Description, and Tags fields
$url = 'https://<YOUR-SEARCH-SERVICE>.search.windows.net/indexes/hotels-quickstart/docs?api-version=2023-11-01&search=restaurant wifi&$count=true&$select=HotelName,Description,Tags'

# Query example 2 
# Apply a filter to the index to find hotels rated 4 or higher
# Returns the HotelName and Rating. Two documents match.
$url = 'https://<YOUR-SEARCH-SERVICE>.search.windows.net/indexes/hotels-quickstart/docs?api-version=2023-11-01&search=*&$filter=Rating gt 4&$select=HotelName,Rating'

# Query example 3
# Take the top two results, and show only HotelName and Category in the results
$url = 'https://<YOUR-SEARCH-SERVICE>.search.windows.net/indexes/hotels-quickstart/docs?api-version=2023-11-01&search=boutique&$top=2&$select=HotelName,Category'

# Query example 4
# Sort by a specific field (Address/City) in ascending order

$url = 'https://<YOUR-SEARCH-SERVICE>.search.windows.net/indexes/hotels-quickstart/docs?api-version=2023-11-01&search=pool&$orderby=Address/City asc&$select=HotelName, Address/City, Tags, Rating'

리소스 정리

본인 소유의 구독으로 이 모듈을 진행하고 있는 경우에는 프로젝트가 끝날 때 여기에서 만든 리소스가 계속 필요한지 확인하는 것이 좋습니다. 계속 실행되는 리소스에는 요금이 부과될 수 있습니다. 리소스를 개별적으로 삭제하거나 리소스 그룹을 삭제하여 전체 리소스 세트를 삭제할 수 있습니다.

포털에서 가장 왼쪽 창의 모든 리소스 또는 리소스 그룹 링크를 사용하여 리소스를 찾고 관리할 수 있습니다.

무료 서비스를 사용하는 경우 인덱스, 인덱서, 데이터 원본 3개로 제한됩니다. 포털에서 개별 항목을 삭제하여 제한 이하로 유지할 수 있습니다.

다음 단계

이 빠른 시작에서는 PowerShell을 사용하여 Azure AI 검색에서 콘텐츠를 만들고 액세스하기 위한 기본 워크플로를 단계별로 실행했습니다. 개념을 염두에 두고 Azure 데이터 원본에서 인덱싱과 같은 고급 시나리오로 이동하는 것이 좋습니다.