快速入门:使用 REST API 在 PowerShell 中创建搜索索引

本 Azure AI 搜索快速入门介绍如何通过使用 PowerShell 和 Azure AI 搜索 REST API 来创建、加载和查询搜索索引。 本文介绍如何以交互方式运行 PowerShell 命令。 你也可以下载并运行一个 PowerShell 脚本来执行相同的操作。

如果没有 Azure 订阅,请在开始前创建一个试用版订阅

先决条件

本快速入门需要以下服务和工具:

复制搜索服务密钥和 URL

在本快速入门中,REST 调用包括每个请求上的服务 URL 和访问密钥。 搜索服务是使用这二者创建的,因此,如果向订阅添加了 Azure AI 搜索,则请按以下步骤获取必需信息。

  1. 登录 Azure 门户。 在搜索服务“概述”页上,获取 URL。 示例终结点可能类似于 https://mydemo.search.azure.cn

  2. 选择“设置>密钥”,然后获取管理密钥以获取服务的完整权限。 会提供两个可互换的管理密钥,以在需要滚动更新其中一个时确保业务连续性。 可以在请求中使用主要或辅助密钥来添加、修改和删除对象。

    显示获取 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.azure.cn/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.azure.cn/$metadata#indexes",
        "value":  [
    
                ]
    }
    

创建索引

除非使用门户,否则服务中必须存在一个索引才能加载数据。 此步骤定义索引并将其推送到服务。 此步骤使用创建索引 REST API

索引的所需元素包括名称和字段集合。 字段集合定义文档的结构。 每个字段都具有名称、类型和确定其用法的属性(例如,该字段在搜索结果中是否可全文搜索、可筛选或可检索)。 在索引中,必须将一个 Edm.String 类型的字段指定为文档标识的键。

此索引已命名为 hotels-quickstart,并具有以下代码中看到的字段定义。 它是其他演练文章中使用的更大的 Hotels 索引的一部分。 为了方便,本快速入门中已对字段定义进行了剪裁。

  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.azure.cn/indexes/hotels-quickstart?api-version=2023-11-01"
    
  3. 使用 $url$headers$body 运行命令,以在服务上创建索引。

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

    结果应类似于此示例,为简洁期间,其仅显示前两个字段:

    {
        "@odata.context":  "https://mydemo.search.azure.cn/$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 参数指定如何编制索引。 有效值包括 uploadmergemergeOrUploaddelete。 该 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 Beijing. A few minutes away is Time's Square and the historic centre of the city, as well as other places of interest that make Beijing 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": "Beijing",
            "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. 将终结点设置为 hotels-quickstart 文档集合,并包括索引操作 (indexes/hotels-quickstart/docs/index)。

    $url = "https://<YOUR-SEARCH-SERVICE>.search.azure.cn/indexes/hotels-quickstart/docs/index?api-version=2023-11-01"
    
  3. 使用 $url$headers$body 运行命令,将文档加载到 hotels-quickstart 索引中。

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

    结果应如以下示例所示。 应会看到状态代码 201

    {
        "@odata.context":  "https://mydemo.search.azure.cn/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. 将终结点设置为 hotels-quickstart 文档集合,并添加参数 search 以传入查询字符串。

    此字符串执行空搜索 (search=*),返回任意文档的未排名列表 (search score = 1.0)。 默认情况下,Azure AI 搜索每次返回 50 个匹配项。 由于已结构化,此查询将返回整个文档结构和值。 添加 $count=true 以获取结果中所有文档的计数。

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

清理资源

在自己的订阅中操作时,最好在项目结束时确定是否仍需要已创建的资源。 持续运行资源可能会产生费用。 可以逐个删除资源,也可以删除资源组以删除整个资源集。

可以在门户中使用最左侧窗格中的“所有资源”或“资源组”链接来查找和管理资源。

如果使用的是免费服务,请记住只能设置三个索引、索引器和数据源。 可以在门户中删除单个项目,以不超出此限制。

后续步骤

在本快速入门中,你已使用 PowerShell 逐步完成了在 Azure AI 搜索中创建和访问内容的基本工作流。 我们建议,在了解相关概念后,继续学习更高级的方案,例如,从 Azure 数据源编制索引: