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
현재 지원되는 환경
- Node.js의 LTS 버전
- Safari, Chrome, Microsoft Edge 및 Firefox의 최신 버전입니다.
자세한 내용은 지원 정책을 참조하세요.
필수 구성 요소
새 검색 서비스를 만들려면 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 세 가지 기본 클라이언트 유형을 통해 이러한 리소스에 대한 작업을 노출합니다.
SearchClient도움이 됩니다.SearchIndexClient를 사용하면 다음을 수행할 수 있습니다.SearchIndexerClient를 사용하면 다음을 수행할 수 있습니다.
참고: 이러한 클라이언트는 호출하는 API가 CORS(Cross-Origin Resource Sharing)를 지원하지 않기 때문에 브라우저에서 작동할 수 없습니다.
TypeScript/JavaScript 관련 개념
문서
검색 인덱스 내에 저장된 항목입니다. 이 문서의 모양은 속성을 사용하여 인덱스에 설명되어 있습니다.fields 각각 SearchField 에는 이름, 데이터 유형 및 추가 메타데이터(예: 검색 가능 또는 필터링 가능한지)가 있습니다.
페이지 매김
일반적으로 한 번에 사용자에게 검색 결과의 하위 집합만 표시 하려고 합니다. 이를 지원하기 위해 , top 및 skip 매개 includeTotalCount변수를 사용하여 검색 결과 위에 페이징된 환경을 제공할 수 있습니다.
문서 필드 인코딩
인덱스에서 지원되는 데이터 유형은 API 요청/응답의 JSON 유형에 매핑됩니다. JS 클라이언트 라이브러리는 다음과 같은 몇 가지 예외를 제외하고 대부분 동일하게 유지됩니다.
-
Edm.DateTimeOffsetJSDate로 변환됩니다. -
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
Azure SDK for JavaScript