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

适用于 JavaScript 的 Azure AI 搜索客户端库 - 版本 12.1.0

Azure AI 搜索(前称为“Azure 认知搜索”)是一个支持 AI 的信息检索平台,可帮助开发人员构建丰富的搜索体验和生成式 AI 应用,将大型语言模型与企业数据相结合。

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

  • 将各种内容类型合并到单个可搜索索引中。 若要填充索引,可以推送包含内容的 JSON 文档,或者如果数据已在 Azure 中,请创建索引器以自动拉取数据。
  • 将技能集附加到索引器,以从图像和非结构化文档创建可搜索内容。 技能集利用 Azure AI 服务中的 API 进行内置 OCR、实体识别、关键短语提取、语言检测、文本翻译和情绪分析。 还可以添加自定义技能,以在数据引入期间集成内容的外部处理。
  • 在搜索客户端应用程序中,实现类似于商业 Web 搜索引擎和聊天样式应用的查询逻辑和用户体验。

使用 @azure/search-documents 客户端库可以:

  • 使用矢量、关键字和混合查询表单提交查询。
  • 为元数据、地理空间搜索、分面导航或基于筛选条件缩小结果范围实现筛选查询。
  • 创建和管理搜索索引。
  • 在搜索索引中上传和更新文档。
  • 创建和管理将数据从 Azure 拉取到索引的索引器。
  • 创建和管理将 AI 扩充添加到数据引入的技能集。
  • 为高级文本分析或多语言内容创建和管理分析器。
  • 通过语义排名和评分配置文件优化结果,以考虑业务逻辑或新鲜度。

关键链接:

开始

安装 @azure/search-documents

npm install @azure/search-documents

当前支持的环境

有关详细信息,请参阅我们的 支持策略

先决条件

若要创建新的搜索服务,可以使用 Azure 门户Azure PowerShellAzure CLI。 下面是使用 Azure CLI 创建免费实例以开始使用的示例:

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

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

对客户端进行身份验证

若要与搜索服务交互,需要创建相应的客户端类的实例:SearchClient 用于搜索索引的文档,SearchIndexClient 用于管理索引,或 SearchIndexerClient 对数据源进行爬网并将搜索文档加载到索引中。 若要实例化客户端对象,需要 终结点Azure 角色API 密钥。 有关使用搜索服务 支持的身份验证方法的详细信息,请参阅文档。

获取 API 密钥

API 密钥可能是一种更简单的入门方法,因为它不需要预先存在的角色分配。

可以从 azure 门户中的搜索服务获取 终结点API 密钥。 有关如何获取 API 密钥的说明,请参阅 文档

或者,可以使用以下 Azure CLI 命令从搜索服务检索 API 密钥:

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

有两种类型的密钥用于访问搜索服务:管理员(读写)查询(只读) 密钥。 限制客户端应用中的访问和操作对于保护服务上的搜索资产至关重要。 始终对源自客户端应用的任何查询使用查询密钥,而不是管理密钥。

注意:上面的 Azure CLI 代码段示例检索管理密钥,以便更轻松地开始探索 API,但应谨慎管理。

获得 API 密钥后,可按如下所示使用它:

const {
  SearchClient,
  SearchIndexClient,
  SearchIndexerClient,
  AzureKeyCredential,
} = require("@azure/search-documents");

// To query and manipulate documents
const searchClient = new SearchClient(
  "<endpoint>",
  "<indexName>",
  new AzureKeyCredential("<apiKey>")
);

// To manage indexes and synonymmaps
const indexClient = new SearchIndexClient("<endpoint>", new AzureKeyCredential("<apiKey>"));

// To manage indexers, datasources and skillsets
const indexerClient = new SearchIndexerClient("<endpoint>", new AzureKeyCredential("<apiKey>"));

在国家云中进行身份验证

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

  • SearchClientOptions 中设置 Audience
const {
  SearchClient,
  SearchIndexClient,
  SearchIndexerClient,
  AzureKeyCredential,
  KnownSearchAudience,
} = require("@azure/search-documents");

// To query and manipulate documents
const searchClient = new SearchClient(
  "<endpoint>",
  "<indexName>",
  new AzureKeyCredential("<apiKey>"),
  {
    audience: KnownSearchAudience.AzureChina,
  }
);

// To manage indexes and synonymmaps
const indexClient = new SearchIndexClient("<endpoint>", new AzureKeyCredential("<apiKey>"), {
  audience: KnownSearchAudience.AzureChina,
});

// To manage indexers, datasources and skillsets
const indexerClient = new SearchIndexerClient("<endpoint>", new AzureKeyCredential("<apiKey>"), {
  audience: KnownSearchAudience.AzureChina,
});

关键概念

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

注意:这些客户端无法在浏览器中运行,因为它调用的 API 不支持跨域资源共享(CORS)。

TypeScript/JavaScript 特定概念

文件

存储在搜索索引内的项。 本文档的形状使用 fields 属性在索引中介绍。 每个 SearchField 都有一个名称、数据类型和其他元数据,例如,它是可搜索或可筛选的。

分页

通常,你只想 一次向用户显示一部分搜索结果。 若要支持此功能,可以使用 topskipincludeTotalCount 参数在搜索结果顶部提供分页体验。

文档字段编码

索引中 支持的数据类型映射到 API 请求/响应中的 JSON 类型。 JS 客户端库主要保留这些库,但有一些例外情况:

  • Edm.DateTimeOffset 转换为 JS Date
  • Edm.GeographyPoint 转换为客户端库导出的 GeographyPoint 类型。
  • number 类型(NaN、Infinity、-Infinity)的特殊值在 REST API 中序列化为字符串,但由客户端库转换回 number

注释:数据类型基于值转换,而不是索引架构中的字段类型。 这意味着,如果你有一个ISO8601日期字符串(例如“2020-03-06T18:48:27.896Z”)作为字段的值,它将转换为日期,而不考虑如何在架构中存储它。

例子

以下示例演示了基础知识 - 请 查看我们的示例 了解更多信息。

创建索引

const { SearchIndexClient, AzureKeyCredential } = require("@azure/search-documents");

const client = new SearchIndexClient("<endpoint>", new AzureKeyCredential("<apiKey>"));

async function main() {
  const result = await client.createIndex({
    name: "example-index",
    fields: [
      {
        type: "Edm.String",
        name: "id",
        key: true,
      },
      {
        type: "Edm.Double",
        name: "awesomenessLevel",
        sortable: true,
        filterable: true,
        facetable: true,
      },
      {
        type: "Edm.String",
        name: "description",
        searchable: true,
      },
      {
        type: "Edm.ComplexType",
        name: "details",
        fields: [
          {
            type: "Collection(Edm.String)",
            name: "tags",
            searchable: true,
          },
        ],
      },
      {
        type: "Edm.Int32",
        name: "hiddenWeight",
        hidden: true,
      },
    ],
  });

  console.log(result);
}

main();

从索引中检索特定文档

可以通过其主键值检索特定文档:

const { SearchClient, AzureKeyCredential } = require("@azure/search-documents");

const client = new SearchClient("<endpoint>", "<indexName>", new AzureKeyCredential("<apiKey>"));

async function main() {
  const result = await client.getDocument("1234");
  console.log(result);
}

main();

将文档添加到索引中

可以将多个文档上传到批内的索引中:

const { SearchClient, AzureKeyCredential } = require("@azure/search-documents");

const client = new SearchClient("<endpoint>", "<indexName>", new AzureKeyCredential("<apiKey>"));

async function main() {
  const uploadResult = await client.uploadDocuments([
    // JSON objects matching the shape of the client's index
    {},
    {},
    {},
  ]);
  for (const result of uploadResult.results) {
    console.log(`Uploaded ${result.key}; succeeded? ${result.succeeded}`);
  }
}

main();

对文档执行搜索

若要列出特定查询的所有结果,可以将 search简单查询语法的搜索字符串配合使用:

const { SearchClient, AzureKeyCredential } = require("@azure/search-documents");

const client = new SearchClient("<endpoint>", "<indexName>", new AzureKeyCredential("<apiKey>"));

async function main() {
  const searchResults = await client.search("wifi -luxury");
  for await (const result of searchResults.results) {
    console.log(result);
  }
}

main();

有关使用 Lucene 语法的更高级搜索,请指定要 fullqueryType

const { SearchClient, AzureKeyCredential } = require("@azure/search-documents");

const client = new SearchClient("<endpoint>", "<indexName>", new AzureKeyCredential("<apiKey>"));

async function main() {
  const searchResults = await client.search('Category:budget AND "recently renovated"^3', {
    queryType: "full",
    searchMode: "all",
  });
  for await (const result of searchResults.results) {
    console.log(result);
  }
}

main();

使用 TypeScript 进行查询

在 TypeScript 中,SearchClient 采用一个泛型参数,该参数是索引文档的模型形状。 这样,就可以对结果中返回的字段执行强类型查找。 TypeScript 还可以检查在指定 select 参数时返回的字段。

import { SearchClient, AzureKeyCredential, SelectFields } from "@azure/search-documents";

// An example schema for documents in the index
interface Hotel {
  hotelId?: string;
  hotelName?: string | null;
  description?: string | null;
  descriptionVector?: Array<number>;
  parkingIncluded?: boolean | null;
  lastRenovationDate?: Date | null;
  rating?: number | null;
  rooms?: Array<{
    beds?: number | null;
    description?: string | null;
  }>;
}

const client = new SearchClient<Hotel>(
  "<endpoint>",
  "<indexName>",
  new AzureKeyCredential("<apiKey>")
);

async function main() {
  const searchResults = await client.search("wifi -luxury", {
    // Only fields in Hotel can be added to this array.
    // TS will complain if one is misspelled.
    select: ["hotelId", "hotelName", "rooms/beds"],
  });

  // These are other ways to declare the correct type for `select`.
  const select = ["hotelId", "hotelName", "rooms/beds"] as const;
  // This declaration lets you opt out of narrowing the TypeScript type of your documents,
  // though the AI Search service will still only return these fields.
  const selectWide: SelectFields<Hotel>[] = ["hotelId", "hotelName", "rooms/beds"];
  // This is an invalid declaration. Passing this to `select` will result in a compiler error
  // unless you opt out of including the model in the client constructor.
  const selectInvalid = ["hotelId", "hotelName", "rooms/beds"];

  for await (const result of searchResults.results) {
    // result.document has hotelId, hotelName, and rating.
    // Trying to access result.document.description would emit a TS error.
    console.log(result.document.hotelName);
  }
}

main();

使用 OData 筛选器进行查询

使用 filter 查询参数,可以使用 OData $filter 表达式的语法查询索引。

const { SearchClient, AzureKeyCredential, odata } = require("@azure/search-documents");

const client = new SearchClient("<endpoint>", "<indexName>", new AzureKeyCredential("<apiKey>"));

async function main() {
  const baseRateMax = 200;
  const ratingMin = 4;
  const searchResults = await client.search("WiFi", {
    filter: odata`Rooms/any(room: room/BaseRate lt ${baseRateMax}) and Rating ge ${ratingMin}`,
    orderBy: ["Rating desc"],
    select: ["hotelId", "hotelName", "Rating"],
  });
  for await (const result of searchResults.results) {
    // Each result will have "HotelId", "HotelName", and "Rating"
    // in addition to the standard search result property "score"
    console.log(result);
  }
}

main();

使用矢量进行查询

可以使用 vector 搜索参数查询文本嵌入。 有关详细信息,请参阅 查询向量筛选向量查询

const { SearchClient, AzureKeyCredential } = require("@azure/search-documents");

const searchClient = new SearchClient(
  "<endpoint>",
  "<indexName>",
  new AzureKeyCredential("<apiKey>")
);

async function main() {
  const queryVector = [...];
  const searchResults = await searchClient.search("*", {
    vectorSearchOptions: {
      queries: [
        {
          kind: "vector",
          vector: queryVector,
          fields: ["descriptionVector"],
          kNearestNeighborsCount: 3,
        },
      ],
    },
  });
  for await (const result of searchResults.results) {
    // These results are the nearest neighbors to the query vector
    console.log(result);
  }
}

main();

使用分面进行查询

分面 用于帮助应用程序用户优化预配置的维度的搜索。 Facet 语法 提供了排序和存储桶方面值的选项。

const { SearchClient, AzureKeyCredential } = require("@azure/search-documents");

const client = new SearchClient("<endpoint>", "<indexName>", new AzureKeyCredential("<apiKey>"));

async function main() {
  const searchResults = await client.search("WiFi", {
    facets: ["category,count:3,sort:count", "rooms/baseRate,interval:100"],
  });
  console.log(searchResults.facets);
  // Output will look like:
  // {
  //   'rooms/baseRate': [
  //     { count: 16, value: 0 },
  //     { count: 17, value: 100 },
  //     { count: 17, value: 200 }
  //   ],
  //   category: [
  //     { count: 5, value: 'Budget' },
  //     { count: 5, value: 'Luxury' },
  //     { count: 5, value: 'Resort and Spa' }
  //   ]
  // }
}

main();

检索结果时,facets 属性将可用,该属性将指示属于每个分面存储桶的结果数。 这可用于驱动优化(例如发出后续搜索,筛选 Rating 大于或等于 3 且小于 4)。

故障 排除

伐木

启用日志记录有助于发现有关故障的有用信息。 若要查看 HTTP 请求和响应的日志,请将 AZURE_LOG_LEVEL 环境变量设置为 info。 或者,可以通过在 @azure/logger中调用 setLogLevel 在运行时启用日志记录:

import { setLogLevel } from "@azure/logger";

setLogLevel("info");

有关如何启用日志的更详细说明,可以查看 @azure/记录器包文档

后续步骤

贡献

若要参与此库,请阅读 贡献指南 了解有关如何生成和测试代码的详细信息。

此项目欢迎贡献和建议。 大多数贡献要求你同意参与者许可协议(CLA),声明你有权(实际这样做)授予我们使用你的贡献的权利。 有关详细信息,请访问 cla.microsoft.com

此项目已采用 Microsoft 开源行为准则。 有关详细信息,请参阅 行为准则常见问题解答 或与 opencode@microsoft.com 联系,了解任何其他问题或意见。

印象