你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

Azure 认知搜索 Java 客户端库 - 版本 11.5.12

这是用于Azure 认知搜索的 Java 客户端库。 Azure 认知搜索服务是一种搜索即服务云解决方案,它为开发人员提供了 API 和工具,用于在 Web、移动和企业应用程序中通过专用、异类内容添加丰富的搜索体验。

Azure 认知搜索服务非常适合以下应用程序方案:

  • 将各种内容类型合并到单个可搜索索引中。 若要填充索引,可以推送包含内容的 JSON 文档,或者,如果数据已在 Azure 中,请创建索引器以自动拉取数据。

  • 将技能集附加到索引器,以从图像和大型文本文档创建可搜索的内容。 技能组利用认知服务中的 AI 进行内置的 OCR、实体识别、关键短语提取、语言检测、文本翻译和情绪分析。 还可以添加自定义技能,以在数据引入期间集成对内容的外部处理。

  • 在搜索客户端应用程序中,实现类似于商业 Web 搜索引擎的查询逻辑和用户体验。

使用 Azure 认知搜索 客户端库可以:

  • 提交包含模糊搜索、通配符搜索和正则表达式的简单和高级查询表单的查询。
  • 实现分面导航、地理空间搜索或基于筛选条件缩小结果的筛选查询。
  • 创建和管理搜索索引。
  • 上传和更新搜索索引中的文档。
  • 创建和管理从 Azure 将数据拉取到索引中的索引器。
  • 创建和管理向数据引入添加 AI 扩充的技能集。
  • 为高级文本分析或多语言内容创建和管理分析器。
  • 通过评分配置文件优化结果,以将业务逻辑或新鲜度考虑在内。

源代码 | 包 (Maven) | API 参考文档| 产品文档 | 样品

入门

添加包

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-search-documents</artifactId>
    <version>11.5.12</version>
</dependency>

先决条件

az search service create --name <mysearch> --resource-group <mysearch-rg> --sku free --location westus

有关可用选项的详细信息 ,请参阅选择定价层

验证客户端

若要与 Azure 认知搜索 服务交互,需要创建 Search Client 类的实例。 若要实现此要求,需要:

  1. URL 终结点
  2. API 密钥

api-key 是验证对搜索服务终结点的访问的唯一机制。 可以从 Azure 门户或通过 Azure CLI 获取 API 密钥:

az search admin-key show --service-name <mysearch> --resource-group <mysearch-rg>

注意:

  • 上面的示例 Azure CLI 代码片段检索管理密钥。 这允许在浏览 API 时更轻松地访问,但应仔细管理 API。
  • 有两种类型的密钥用于访问搜索服务: 管理员 (读写) 查询 (只读) 密钥。 限制客户端应用中的访问和操作对于保护服务中的搜索资产至关重要。 对于源自客户端应用的任何查询,请始终使用查询密钥而不是管理密钥。

SDK 提供三个客户端。

  • SearchIndexClient 用于索引和同义词映射上的 CRUD 操作。
  • SearchIndexerClient 用于索引器、日期源和技能集上的 CRUD 操作。
  • SearchClient 用于所有文档操作。

创建 SearchIndexClient

若要创建 ,SearchIndexClient/SearchIndexAsyncClient需要Azure 认知搜索服务 URL 终结点和管理员密钥的值。

SearchIndexClient searchIndexClient = new SearchIndexClientBuilder()
    .endpoint(endpoint)
    .credential(new AzureKeyCredential(apiKey))
    .buildClient();

SearchIndexAsyncClient searchIndexAsyncClient = new SearchIndexClientBuilder()
    .endpoint(endpoint)
    .credential(new AzureKeyCredential(apiKey))
    .buildAsyncClient();

创建 SearchIndexerClient

若要创建 ,SearchIndexerClient/SearchIndexerAsyncClient需要Azure 认知搜索服务 URL 终结点和管理员密钥的值。

SearchIndexerClient searchIndexerClient = new SearchIndexerClientBuilder()
    .endpoint(endpoint)
    .credential(new AzureKeyCredential(apiKey))
    .buildClient();

SearchIndexerAsyncClient searchIndexerAsyncClient = new SearchIndexerClientBuilder()
    .endpoint(endpoint)
    .credential(new AzureKeyCredential(apiKey))
    .buildAsyncClient();

创建 SearchClient

获得 Azure 认知搜索 服务 URL 终结点和管理密钥的值后,可以使用现有索引名称创建 SearchClient/SearchAsyncClient

SearchClient searchClient = new SearchClientBuilder()
    .endpoint(endpoint)
    .credential(new AzureKeyCredential(adminKey))
    .indexName(indexName)
    .buildClient();

SearchAsyncClient searchAsyncClient = new SearchClientBuilder()
    .endpoint(endpoint)
    .credential(new AzureKeyCredential(adminKey))
    .indexName(indexName)
    .buildAsyncClient();

发送第一个搜索查询

若要使用 Azure 认知搜索首先按照本指南创建索引。 创建索引后,可以使用以下示例开始使用 SDK。

关键概念

Azure 认知搜索服务包含一个或多个索引,这些索引以 JSON 文档的形式提供可搜索数据的持久存储。 (如果你不熟悉搜索,可以在索引和数据库表之间进行非常粗略的类比。) 客户端azure-search-documents库通过两种main客户端类型公开对这些资源执行的操作。

示例

以下示例都使用一个简单的 Hotel 数据集,可以从Azure 门户导入到自己的索引中。这些只是一些基础知识 - 请检查我们的示例获取更多内容。

查询

可通过两种方式与从搜索查询返回的数据进行交互。

让我们通过搜索“豪华”酒店来探索它们。

使用 SearchDocument like a dictionary for search results

SearchDocument 是未提供自己的查询时返回的默认类型。 在这里,我们将执行搜索,枚举结果,并使用 SearchDocument的字典索引器提取数据。

for (SearchResult searchResult : searchClient.search("luxury")) {
    SearchDocument doc = searchResult.getDocument(SearchDocument.class);
    String id = (String) doc.get("hotelId");
    String name = (String) doc.get("hotelName");
    System.out.printf("This is hotelId %s, and this is hotel name %s.%n", id, name);
}

对搜索结果使用 Java 模型类

定义 Hotel 类。

public class Hotel {
    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public Hotel setId(String id) {
        this.id = id;
        return this;
    }

    public String getName() {
        return name;
    }

    public Hotel setName(String name) {
        this.name = name;
        return this;
    }
}

在查询时使用它来代替 SearchDocument

for (SearchResult searchResult : searchClient.search("luxury")) {
    Hotel doc = searchResult.getDocument(Hotel.class);
    String id = doc.getId();
    String name = doc.getName();
    System.out.printf("This is hotelId %s, and this is hotel name %s.%n", id, name);
}

在知道搜索索引的架构后,建议创建 Java 模型类。

搜索选项

SearchOptions提供对查询行为的有力控制。

我们来搜索评级良好的前 5 家豪华酒店。

SearchOptions options = new SearchOptions()
    .setFilter("rating ge 4")
    .setOrderBy("rating desc")
    .setTop(5);
SearchPagedIterable searchResultsIterable = searchClient.search("luxury", options, Context.NONE);
// ...

创建索引

可以使用 SearchIndexClient 创建搜索索引。 索引还可以定义建议器、词法分析器等。

有多种方法可以准备搜索索引的搜索字段。 对于基本需求,我们在 和 中提供了静态帮助程序方法buildSearchFields,该方法可将 Java POJO 类转换为 List<SearchField>SearchIndexClientSearchIndexAsyncClient 有三个 SimpleFieldProperty注释 , SearchFieldPropertyFieldBuilderIgnore 用于配置模型类的 字段。

List<SearchField> searchFields = SearchIndexClient.buildSearchFields(Hotel.class, null);
searchIndexClient.createIndex(new SearchIndex("index", searchFields));

对于高级方案,可以直接使用 SearchField 生成搜索字段。

List<SearchField> searchFieldList = new ArrayList<>();
searchFieldList.add(new SearchField("hotelId", SearchFieldDataType.STRING)
    .setKey(true)
    .setFilterable(true)
    .setSortable(true));

searchFieldList.add(new SearchField("hotelName", SearchFieldDataType.STRING)
    .setSearchable(true)
    .setFilterable(true)
    .setSortable(true));
searchFieldList.add(new SearchField("description", SearchFieldDataType.STRING)
    .setSearchable(true)
    .setAnalyzerName(LexicalAnalyzerName.EU_LUCENE));
searchFieldList.add(new SearchField("tags", SearchFieldDataType.collection(SearchFieldDataType.STRING))
    .setSearchable(true)
    .setFilterable(true)
    .setFacetable(true));
searchFieldList.add(new SearchField("address", SearchFieldDataType.COMPLEX)
    .setFields(new SearchField("streetAddress", SearchFieldDataType.STRING).setSearchable(true),
        new SearchField("city", SearchFieldDataType.STRING)
            .setSearchable(true)
            .setFilterable(true)
            .setFacetable(true)
            .setSortable(true),
        new SearchField("stateProvince", SearchFieldDataType.STRING)
            .setSearchable(true)
            .setFilterable(true)
            .setFacetable(true)
            .setSortable(true),
        new SearchField("country", SearchFieldDataType.STRING)
            .setSearchable(true)
            .setFilterable(true)
            .setFacetable(true)
            .setSortable(true),
        new SearchField("postalCode", SearchFieldDataType.STRING)
            .setSearchable(true)
            .setFilterable(true)
            .setFacetable(true)
            .setSortable(true)
    ));

// Prepare suggester.
SearchSuggester suggester = new SearchSuggester("sg", Collections.singletonList("hotelName"));
// Prepare SearchIndex with index name and search fields.
SearchIndex index = new SearchIndex("hotels").setFields(searchFieldList).setSuggesters(suggester);
// Create an index
searchIndexClient.createIndex(index);

从索引中检索特定文档

除了使用关键字和可选筛选器查询文档外,如果已知道关键字,还可以从索引中检索特定文档。 例如,可以从查询中获取密钥,并希望显示有关它的详细信息或将客户导航到该文档。

Hotel hotel = searchClient.getDocument("1", Hotel.class);
System.out.printf("This is hotelId %s, and this is hotel name %s.%n", hotel.getId(), hotel.getName());

将文档添加到索引

可以在UploadMerge单个批处理请求中从索引、、 MergeOrUploadDelete多个文档。 需要注意 一些特殊的合并规则

IndexDocumentsBatch<Hotel> batch = new IndexDocumentsBatch<>();
batch.addUploadActions(Collections.singletonList(new Hotel().setId("783").setName("Upload Inn")));
batch.addMergeActions(Collections.singletonList(new Hotel().setId("12").setName("Renovated Ranch")));
searchClient.indexDocuments(batch);

默认情况下,如果任何单个操作失败,请求将引发 IndexBatchException ,你可以使用 findFailedActionsToRetry 对失败的文档重试。 还有一个选项 throwOnAnyError ,你可以将其设置为 false ,以便通过 IndexDocumentsResult 检查获取成功的响应。

异步 API

到目前为止,这些示例一直使用同步 API,但我们也提供对异步 API 的完全支持。 需要使用 SearchAsyncClient

searchAsyncClient.search("luxury")
    .subscribe(result -> {
        Hotel hotel = result.getDocument(Hotel.class);
        System.out.printf("This is hotelId %s, and this is hotel name %s.%n", hotel.getId(), hotel.getName());
    });

在国家云中进行身份验证

若要在国家 中进行身份验证,需要对客户端配置进行以下添加:

  • AuthorityHost凭据选项中或通过环境变量设置AZURE_AUTHORITY_HOST
  • audienceSearchIndexClientBuilder或 中SearchClientBuilder设置SearchIndexerClientBuilder
// Create a SearchClient that will authenticate through AAD in the China national cloud.
SearchClient searchClient = new SearchClientBuilder()
    .endpoint(endpoint)
    .indexName(indexName)
    .credential(new DefaultAzureCredentialBuilder()
        .authorityHost(AzureAuthorityHosts.AZURE_CHINA)
        .build())
    .audience(SearchAudience.AZURE_CHINA)
    .buildClient();

疑难解答

常规

使用此 Java 客户端库与 Azure 认知搜索 交互时,服务返回的错误对应于为 REST API 请求返回的相同 HTTP 状态代码。 例如,如果尝试检索索引中不存在的文档,服务将返回 404 错误。

处理搜索错误响应

任何失败的搜索 API 操作都将引发具有 HttpResponseException 有用 的 Status codes。 其中许多错误是可恢复的。

try {
    Iterable<SearchResult> results = searchClient.search("hotel");
} catch (HttpResponseException ex) {
    // The exception contains the HTTP status code and the detailed message
    // returned from the search service
    HttpResponse response = ex.getResponse();
    System.out.println("Status Code: " + response.getStatusCode());
    System.out.println("Message: " + ex.getMessage());
}

如果想要更深入地了解针对服务发出的请求,还可以轻松启用控制台记录

启用日志记录

适用于 Java 的 Azure SDK 提供一致的日志记录案例,有助于排查应用程序错误并加快解决。 生成的日志会在到达终端状态之前捕获应用程序的流,以帮助查找根本问题。 查看 日志记录 Wiki,获取有关启用日志记录的指南。

默认的 HTTP 客户端

默认情况下,将使用基于 Netty 的 HTTP 客户端。 HTTP 客户端 Wiki 提供了有关配置或更改 HTTP 客户端的详细信息。

后续步骤

贡献

本项目欢迎贡献和建议。 大多数贡献要求你同意贡献者许可协议 (CLA),并声明你有权(并且确实有权)授予我们使用你的贡献的权利。

提交拉取请求时,CLA 机器人将自动确定你是否需要提供 CLA,并相应地修饰 PR(例如标签、注释)。 直接按机器人提供的说明操作。 只需使用 CLA 对所有存储库执行一次这样的操作。

此项目采用了 Microsoft 开放源代码行为准则。 有关详细信息,请参阅行为准则常见问题解答,或如果有任何其他问题或意见,请与 联系。

曝光数