다음을 통해 공유


JavaScript용 Azure AI Search 클라이언트 라이브러리 - 버전 12.2.0

Azure AI Search (이전의 "Azure Cognitive Search")는 개발자가 대규모 언어 모델과 엔터프라이즈 데이터를 결합하는 풍부한 검색 환경 및 생성형 AI 앱을 빌드하는 데 도움이 되는 AI 기반 정보 검색 플랫폼입니다.

Azure AI Search 서비스는 다음 애플리케이션 시나리오에 적합합니다.

  • 다양한 콘텐츠 형식을 검색 가능한 단일 인덱스로 통합합니다. 인덱스를 채우려면 콘텐츠가 포함된 JSON 문서를 푸시하거나 데이터가 이미 Azure에 있는 경우 데이터를 자동으로 끌어올 인덱서를 만들 수 있습니다.
  • 인덱서에 기술 세트를 연결하여 이미지 및 구조화되지 않은 문서에서 검색 가능한 콘텐츠를 만듭니다. 기술 세트는 기본 제공 OCR, 엔터티 인식, 핵심 구 추출, 언어 감지, 텍스트 번역 및 감정 분석을 위해 Azure AI Services의 API를 활용합니다. 사용자 지정 기술을 추가하여 데이터 수집 중에 콘텐츠의 외부 처리를 통합할 수도 있습니다.
  • 검색 클라이언트 애플리케이션에서 상용 웹 검색 엔진 및 채팅 스타일 앱과 유사한 쿼리 논리 및 사용자 환경을 구현합니다.

클라이언트 라이브러리를 @azure/search-documents 사용하여 다음을 수행할 수 있습니다.

  • 벡터, 키워드 및 하이브리드 쿼리 양식을 사용하여 쿼리를 제출합니다.
  • 메타데이터, 지리 공간적 검색, 패싯 탐색 또는 필터 조건에 따라 결과의 범위를 좁히기 위해 필터링된 쿼리를 구현합니다.
  • 검색 인덱스를 만들고 관리합니다.
  • 검색 인덱스로 문서를 업로드하고 업데이트합니다.
  • Azure에서 인덱스로 데이터를 끌어오는 인덱서를 만들고 관리합니다.
  • 데이터 수집에 AI 보강을 추가하는 기술 세트를 만들고 관리합니다.
  • 고급 텍스트 분석 또는 다국어 콘텐츠를 위한 분석기를 만들고 관리합니다.
  • 의미 체계 순위 및 점수 매기기 프로필을 통해 결과를 최적화하여 비즈니스 논리 또는 새로 고침을 고려합니다.

키 링크:

시작

@azure/search-documents 패키지 설치

npm install @azure/search-documents

현재 지원되는 환경

자세한 내용은 지원 정책을 참조하세요.

필수 구성 요소

새 검색 서비스를 만들려면 Azure Portal, Azure PowerShell 또는 Azure 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 Portal의 검색 서비스에서 엔드포인트API 키를 가져올 수 있습니다. API 키를 가져오는 방법에 대한 지침은 설명서 를 참조하세요.

또는 다음 Azure CLI 명령을 사용하여 검색 서비스에서 API 키를 검색할 수 있습니다.

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

검색 서비스에 액세스하는 데 사용되는 키에는 admin(읽기-쓰기)query(읽기 전용) 키의 두 가지 유형이 있습니다. 클라이언트 앱에서 액세스 및 작업을 제한하는 것은 서비스의 검색 자산을 보호하는 데 필수적입니다. 항상 클라이언트 앱에서 시작된 모든 쿼리에 대해 관리 키가 아닌 쿼리 키를 사용합니다.

참고: 위의 예제 Azure CLI 코드 조각은 API 탐색을 더 쉽게 시작할 수 있도록 관리 키를 검색하지만 신중하게 관리해야 합니다.

api-key가 있으면 다음과 같이 사용할 수 있습니다.

import {
  SearchClient,
  AzureKeyCredential,
  SearchIndexClient,
  SearchIndexerClient,
} from "@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>"));

국가별 클라우드에서 인증

National Cloud에서 인증하려면 클라이언트 구성에 다음과 같은 사항을 추가해야 합니다.

  • Audience 에서SearchClientOptions
import {
  SearchClient,
  AzureKeyCredential,
  KnownSearchAudience,
  SearchIndexClient,
  SearchIndexerClient,
} from "@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 Search 서비스에는 JSON 문서 형식으로 검색 가능한 데이터의 영구 스토리지를 제공하는 하나 이상의 인덱스가 포함되어 있습니다. (검색이 처음이라면 인덱스와 데이터베이스 테이블을 매우 대략적으로 비유할 수 있습니다.) 클라이언트 라이브러리는 @azure/search-documents 세 가지 기본 클라이언트 유형을 통해 이러한 리소스에 대한 작업을 노출합니다.

참고: 이러한 클라이언트는 호출하는 API가 CORS(Cross-Origin Resource Sharing)를 지원하지 않기 때문에 브라우저에서 작동할 수 없습니다.

TypeScript/JavaScript 관련 개념

문서

검색 인덱스 내에 저장된 항목입니다. 이 문서의 모양은 속성을 사용하여 인덱스에 설명되어 있습니다.fields 각각 SearchField 에는 이름, 데이터 유형 및 추가 메타데이터(예: 검색 가능 또는 필터링 가능한지)가 있습니다.

페이지 매김

일반적으로 한 번에 사용자에게 검색 결과의 하위 집합만 표시 하려고 합니다. 이를 지원하기 위해 , topskip 매개 includeTotalCount변수를 사용하여 검색 결과 위에 페이징된 환경을 제공할 수 있습니다.

문서 필드 인코딩

인덱스에서 지원되는 데이터 유형은 API 요청/응답의 JSON 유형에 매핑됩니다. JS 클라이언트 라이브러리는 다음과 같은 몇 가지 예외를 제외하고 대부분 동일하게 유지됩니다.

  • Edm.DateTimeOffset JS Date로 변환됩니다.
  • Edm.GeographyPoint 클라이언트 라이브러리에서 내보낸 형식으로 변환 GeographyPoint 됩니다.
  • 유형(NaN, Infinity, -Infinity)의 number 특수 값은 REST API에서 문자열로 직렬화되지만 클라이언트 라이브러리에 의해 다시 number 변환됩니다.

참고: 데이터 유형은 인덱스 스키마의 필드 유형이 아닌 값을 기반으로 변환됩니다. 즉, 필드 값으로 ISO8601 Date 문자열(예: "2020-03-06T18:48:27.896Z")이 있는 경우 스키마에 저장한 방법에 관계없이 날짜로 변환됩니다.

예제

다음 예제는 기본 사항을 보여줍니다 - 자세한 내용은 샘플을 확인하십시오 .

인덱스 만들기

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

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

const result = await indexClient.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(`Index created with name ${result.name}`);

인덱스에서 특정 문서 검색

특정 문서는 기본 키 값으로 검색할 수 있습니다.

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

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

const result = await searchClient.getDocument("1234");

인덱스로 문서 추가

일괄 처리 내의 인덱스로 여러 문서를 업로드할 수 있습니다.

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

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

const uploadResult = await searchClient.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}`);
}

문서에 대한 검색 수행

특정 쿼리의 모든 결과를 나열하려면 search을 사용하는 검색 문자열과 함께 사용할 수 있습니다.

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

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

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

Lucene 구문을 사용하는 고급 검색의 경우 다음과 같이 queryType지정합니다full.

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

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

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

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 searchClient = new SearchClient<Hotel>(
  "<endpoint>",
  "<indexName>",
  new AzureKeyCredential("<apiKey>"),
);

const searchResults = await searchClient.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);
}

OData 필터를 사용하여 쿼리

query 매개 변수를 filter 사용하면 OData $filter 식의 구문을 사용하여 인덱스를 쿼리할 수 있습니다.

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

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

const baseRateMax = 200;
const ratingMin = 4;
const searchResults = await searchClient.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);
}

벡터를 사용하여 쿼리

텍스트 임베딩은 search 매개 변수를 vector 사용하여 쿼리할 수 있습니다. 자세한 내용은 쿼리 벡터벡터 쿼리 필터링을 참조하세요.

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

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

const queryVector: number[] = [
  // Embedding of the query "What are the most luxurious hotels?"
];
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);
}

패싯을 사용하여 쿼리

패싯 은 애플리케이션 사용자가 사전 구성된 차원을 따라 검색을 구체화하는 데 사용됩니다. 패싯 구문은 패싯 값을 정렬하고 버킷하는 옵션을 제공합니다.

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

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

const searchResults = await searchClient.search("WiFi", {
  facets: ["category,count:3,sort:count", "rooms/baseRate,interval:100"],
});
console.log(searchResults.facets);

결과를 facets 검색할 때 각 패싯 버킷에 속하는 결과 수를 나타내는 속성을 사용할 수 있습니다. 이는 세분화를 추진하는 데 사용할 수 있습니다(예: 3 이상 4 미만인 것을 Rating 필터링하는 후속 검색 실행).

문제 해결

로깅

로깅을 사용하도록 설정하면 오류에 대한 유용한 정보를 파악하는 데 도움이 될 수 있습니다. HTTP 요청 및 응답 로그를 보려면 AZURE_LOG_LEVEL 환경 변수를 info설정합니다. 또는 setLogLevel@azure/logger 호출하여 런타임에 로깅을 사용하도록 설정할 수 있습니다.

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

setLogLevel("info");

로그를 사용하도록 설정하는 방법에 대한 자세한 지침은 @azure/로거 패키지 문서를 참조하세요.

다음 단계

기여

이 라이브러리에 기여하려면 기여 가이드 를 참조하여 코드를 빌드하고 테스트하는 방법에 대해 자세히 알아보세요.

이 프로젝트는 기여와 제안을 환영합니다. 대부분의 기여는 귀하가 귀하의 기여를 사용할 권리를 부여할 권리가 있음을 선언하는 CLA(기여자 사용권 계약)에 동의해야 합니다. 자세한 내용은 cla.microsoft.com 를 참조하십시오.

이 프로젝트는 Microsoft 오픈 소스 준수 사항을 채택했습니다. 자세한 내용은 행동 강령 FAQ 참조하거나 추가 질문이나 의견을 opencode@microsoft.com 문의하세요.

  • JavaScript용 Microsoft Azure SDK