Build search applications using Azure AI Search SDK for JavaScript (@azure/search-documents). Use when creating/managing indexes, implementing vector/hybrid search, semantic ranking, or building agentic retrieval with knowledge bases.
Add this skill
npx mdskills install sickn33/azure-search-documents-tsComprehensive SDK documentation with vector, hybrid, and semantic search patterns for Azure AI Search
1---2name: azure-search-documents-ts3description: Build search applications using Azure AI Search SDK for JavaScript (@azure/search-documents). Use when creating/managing indexes, implementing vector/hybrid search, semantic ranking, or building agentic retrieval with knowledge bases.4package: "@azure/search-documents"5---67# Azure AI Search SDK for TypeScript89Build search applications with vector, hybrid, and semantic search capabilities.1011## Installation1213```bash14npm install @azure/search-documents @azure/identity15```1617## Environment Variables1819```bash20AZURE_SEARCH_ENDPOINT=https://<service-name>.search.windows.net21AZURE_SEARCH_INDEX_NAME=my-index22AZURE_SEARCH_ADMIN_KEY=<admin-key> # Optional if using Entra ID23```2425## Authentication2627```typescript28import { SearchClient, SearchIndexClient } from "@azure/search-documents";29import { DefaultAzureCredential } from "@azure/identity";3031const endpoint = process.env.AZURE_SEARCH_ENDPOINT!;32const indexName = process.env.AZURE_SEARCH_INDEX_NAME!;33const credential = new DefaultAzureCredential();3435// For searching36const searchClient = new SearchClient(endpoint, indexName, credential);3738// For index management39const indexClient = new SearchIndexClient(endpoint, credential);40```4142## Core Workflow4344### Create Index with Vector Field4546```typescript47import { SearchIndex, SearchField, VectorSearch } from "@azure/search-documents";4849const index: SearchIndex = {50 name: "products",51 fields: [52 { name: "id", type: "Edm.String", key: true },53 { name: "title", type: "Edm.String", searchable: true },54 { name: "description", type: "Edm.String", searchable: true },55 { name: "category", type: "Edm.String", filterable: true, facetable: true },56 {57 name: "embedding",58 type: "Collection(Edm.Single)",59 searchable: true,60 vectorSearchDimensions: 1536,61 vectorSearchProfileName: "vector-profile",62 },63 ],64 vectorSearch: {65 algorithms: [66 { name: "hnsw-algorithm", kind: "hnsw" },67 ],68 profiles: [69 { name: "vector-profile", algorithmConfigurationName: "hnsw-algorithm" },70 ],71 },72};7374await indexClient.createOrUpdateIndex(index);75```7677### Index Documents7879```typescript80const documents = [81 { id: "1", title: "Widget", description: "A useful widget", category: "Tools", embedding: [...] },82 { id: "2", title: "Gadget", description: "A cool gadget", category: "Electronics", embedding: [...] },83];8485const result = await searchClient.uploadDocuments(documents);86console.log(`Indexed ${result.results.length} documents`);87```8889### Full-Text Search9091```typescript92const results = await searchClient.search("widget", {93 select: ["id", "title", "description"],94 filter: "category eq 'Tools'",95 orderBy: ["title asc"],96 top: 10,97});9899for await (const result of results.results) {100 console.log(`${result.document.title}: ${result.score}`);101}102```103104### Vector Search105106```typescript107const queryVector = await getEmbedding("useful tool"); // Your embedding function108109const results = await searchClient.search("*", {110 vectorSearchOptions: {111 queries: [112 {113 kind: "vector",114 vector: queryVector,115 fields: ["embedding"],116 kNearestNeighborsCount: 10,117 },118 ],119 },120 select: ["id", "title", "description"],121});122123for await (const result of results.results) {124 console.log(`${result.document.title}: ${result.score}`);125}126```127128### Hybrid Search (Text + Vector)129130```typescript131const queryVector = await getEmbedding("useful tool");132133const results = await searchClient.search("tool", {134 vectorSearchOptions: {135 queries: [136 {137 kind: "vector",138 vector: queryVector,139 fields: ["embedding"],140 kNearestNeighborsCount: 50,141 },142 ],143 },144 select: ["id", "title", "description"],145 top: 10,146});147```148149### Semantic Search150151```typescript152// Index must have semantic configuration153const index: SearchIndex = {154 name: "products",155 fields: [...],156 semanticSearch: {157 configurations: [158 {159 name: "semantic-config",160 prioritizedFields: {161 titleField: { name: "title" },162 contentFields: [{ name: "description" }],163 },164 },165 ],166 },167};168169// Search with semantic ranking170const results = await searchClient.search("best tool for the job", {171 queryType: "semantic",172 semanticSearchOptions: {173 configurationName: "semantic-config",174 captions: { captionType: "extractive" },175 answers: { answerType: "extractive", count: 3 },176 },177 select: ["id", "title", "description"],178});179180for await (const result of results.results) {181 console.log(`${result.document.title}`);182 console.log(` Caption: ${result.captions?.[0]?.text}`);183 console.log(` Reranker Score: ${result.rerankerScore}`);184}185```186187## Filtering and Facets188189```typescript190// Filter syntax191const results = await searchClient.search("*", {192 filter: "category eq 'Electronics' and price lt 100",193 facets: ["category,count:10", "brand"],194});195196// Access facets197for (const [facetName, facetResults] of Object.entries(results.facets || {})) {198 console.log(`${facetName}:`);199 for (const facet of facetResults) {200 console.log(` ${facet.value}: ${facet.count}`);201 }202}203```204205## Autocomplete and Suggestions206207```typescript208// Create suggester in index209const index: SearchIndex = {210 name: "products",211 fields: [...],212 suggesters: [213 { name: "sg", sourceFields: ["title", "description"] },214 ],215};216217// Autocomplete218const autocomplete = await searchClient.autocomplete("wid", "sg", {219 mode: "twoTerms",220 top: 5,221});222223// Suggestions224const suggestions = await searchClient.suggest("wid", "sg", {225 select: ["title"],226 top: 5,227});228```229230## Batch Operations231232```typescript233// Batch upload, merge, delete234const batch = [235 { upload: { id: "1", title: "New Item" } },236 { merge: { id: "2", title: "Updated Title" } },237 { delete: { id: "3" } },238];239240const result = await searchClient.indexDocuments({ actions: batch });241```242243## Key Types244245```typescript246import {247 SearchClient,248 SearchIndexClient,249 SearchIndexerClient,250 SearchIndex,251 SearchField,252 SearchOptions,253 VectorSearch,254 SemanticSearch,255 SearchIterator,256} from "@azure/search-documents";257```258259## Best Practices2602611. **Use hybrid search** - Combine vector + text for best results2622. **Enable semantic ranking** - Improves relevance for natural language queries2633. **Batch document uploads** - Use `uploadDocuments` with arrays, not single docs2644. **Use filters for security** - Implement document-level security with filters2655. **Index incrementally** - Use `mergeOrUploadDocuments` for updates2666. **Monitor query performance** - Use `includeTotalCount: true` sparingly in production267
Full transparency — inspect the skill content before installing.