{
  "schema": "https://ai-atoms.com/schemas/skill-v1.json",
  "type": "skill",
  "id": "skill/azure-search-documents-ts",
  "version": "1.0.0",
  "name": "Azure Search Documents Ts",
  "description": "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 ag...",
  "system_prompt_fragment": "# Azure AI Search SDK for TypeScript\n\nBuild search applications with vector, hybrid, and semantic search capabilities.\n\n## Installation\n\n```bash\nnpm install @azure/search-documents @azure/identity\n```\n\n## Environment Variables\n\n```bash\nAZURE_SEARCH_ENDPOINT=https://<service-name>.search.windows.net\nAZURE_SEARCH_INDEX_NAME=my-index\nAZURE_SEARCH_ADMIN_KEY=<admin-key>  # Optional if using Entra ID\n```\n\n## Authentication\n\n```typescript\nimport { SearchClient, SearchIndexClient } from \"@azure/search-documents\";\nimport { DefaultAzureCredential } from \"@azure/identity\";\n\nconst endpoint = process.env.AZURE_SEARCH_ENDPOINT!;\nconst indexName = process.env.AZURE_SEARCH_INDEX_NAME!;\nconst credential = new DefaultAzureCredential();\n\n// For searching\nconst searchClient = new SearchClient(endpoint, indexName, credential);\n\n// For index management\nconst indexClient = new SearchIndexClient(endpoint, credential);\n```\n\n## Core Workflow\n\n### Create Index with Vector Field\n\n```typescript\nimport { SearchIndex, SearchField, VectorSearch } from \"@azure/search-documents\";\n\nconst index: SearchIndex = {\n  name: \"products\",\n  fields: [\n    { name: \"id\", type: \"Edm.String\", key: true },\n    { name: \"title\", type: \"Edm.String\", searchable: true },\n    { name: \"description\", type: \"Edm.String\", searchable: true },\n    { name: \"category\", type: \"Edm.String\", filterable: true, facetable: true },\n    {\n      name: \"embedding\",\n      type: \"Collection(Edm.Single)\",\n      searchable: true,\n      vectorSearchDimensions: 1536,\n      vectorSearchProfileName: \"vector-profile\",\n    },\n  ],\n  vectorSearch: {\n    algorithms: [\n      { name: \"hnsw-algorithm\", kind: \"hnsw\" },\n    ],\n    profiles: [\n      { name: \"vector-profile\", algorithmConfigurationName: \"hnsw-algorithm\" },\n    ],\n  },\n};\n\nawait indexClient.createOrUpdateIndex(index);\n```\n\n### Index Documents\n\n```typescript\nconst documents = [\n  { id: \"1\", title: \"Widget\", description: \"A useful widget\", category: \"Tools\", embedding: [...] },\n  { id: \"2\", title: \"Gadget\", description: \"A cool gadget\", category: \"Electronics\", embedding: [...] },\n];\n\nconst result = await searchClient.uploadDocuments(documents);\nconsole.log(`Indexed ${result.results.length} documents`);\n```\n\n### Full-Text Search\n\n```typescript\nconst results = await searchClient.search(\"widget\", {\n  select: [\"id\", \"title\", \"description\"],\n  filter: \"category eq 'Tools'\",\n  orderBy: [\"title asc\"],\n  top: 10,\n});\n\nfor await (const result of results.results) {\n  console.log(`${result.document.title}: ${result.score}`);\n}\n```\n\n### Vector Search\n\n```typescript\nconst queryVector = await getEmbedding(\"useful tool\"); // Your embedding function\n\nconst results = await searchClient.search(\"*\", {\n  vectorSearchOptions: {\n    queries: [\n      {\n        kind: \"vector\",\n        vector: queryVector,\n        fields: [\"embedding\"],\n        kNearestNeighborsCount: 10,\n      },\n    ],\n  },\n  select: [\"id\", \"title\", \"description\"],\n});\n\nfor await (const result of results.results) {\n  console.log(`${result.document.title}: ${result.score}`);\n}\n```\n\n### Hybrid Search (Text + Vector)\n\n```typescript\nconst queryVector = await getEmbedding(\"useful tool\");\n\nconst results = await searchClient.search(\"tool\", {\n  vectorSearchOptions: {\n    queries: [\n      {\n        kind: \"vector\",\n        vector: queryVector,\n        fields: [\"embedding\"],\n        kNearestNeighborsCount: 50,\n      },\n    ],\n  },\n  select: [\"id\", \"title\", \"description\"],\n  top: 10,\n});\n```\n\n### Semantic Search\n\n```typescript\n// Index must have semantic configuration\nconst index: SearchIndex = {\n  name: \"products\",\n  fields: [...],\n  semanticSearch: {\n    configurations: [\n      {\n        name: \"semantic-config\",\n        prioritizedFields: {\n          titleField: { name: \"title\" },\n          contentFields: [{ name: \"description\" }],\n        },\n      },\n    ],\n  },\n};\n\n// Search with semantic ranking\nconst results = await searchClient.search(\"best tool for the job\", {\n  queryType: \"semantic\",\n  semanticSearchOptions: {\n    configurationName: \"semantic-config\",\n    captions: { captionType: \"extractive\" },\n    answers: { answerType: \"extractive\", count: 3 },\n  },\n  select: [\"id\", \"title\", \"description\"],\n});\n\nfor await (const result of results.results) {\n  console.log(`${result.document.title}`);\n  console.log(`  Caption: ${result.captions?.[0]?.text}`);\n  console.log(`  Reranker Score: ${result.rerankerScore}`);\n}\n```\n\n## Filtering and Facets\n\n```typescript\n// Filter syntax\nconst results = await searchClient.search(\"*\", {\n  filter: \"category eq 'Electronics' and price lt 100\",\n  facets: [\"category,count:10\", \"brand\"],\n});\n\n// Access facets\nfor (const [facetName, facetResults] of Object.entries(results.facets || {})) {\n  console.log(`${facetName}:`);\n  for (const facet of facetResults) {\n    console.log(`  ${facet.value}: ${facet.count}`);\n  }\n}\n```\n\n## Autocomplete and Suggestions\n\n```typescript\n// Create suggester in index\nconst index: SearchIndex = {\n  name: \"products\",\n  fields: [...],\n  suggesters: [\n    { name: \"sg\", sourceFields: [\"title\", \"description\"] },\n  ],\n};\n\n// Autocomplete\nconst autocomplete = await searchClient.autocomplete(\"wid\", \"sg\", {\n  mode: \"twoTerms\",\n  top: 5,\n});\n\n// Suggestions\nconst suggestions = await searchClient.suggest(\"wid\", \"sg\", {\n  select: [\"title\"],\n  top: 5,\n});\n```\n\n## Batch Operations\n\n```typescript\n// Batch upload, merge, delete\nconst batch = [\n  { upload: { id: \"1\", title: \"New Item\" } },\n  { merge: { id: \"2\", title: \"Updated Title\" } },\n  { delete: { id: \"3\" } },\n];\n\nconst result = await searchClient.indexDocuments({ actions: batch });\n```\n\n## Key Types\n\n```typescript\nimport {\n  SearchClient,\n  SearchIndexClient,\n  SearchIndexerClient,\n  SearchIndex,\n  SearchField,\n  SearchOptions,\n  VectorSearch,\n  SemanticSearch,\n  SearchIterator,\n} from \"@azure/search-documents\";\n```\n\n## Best Practices\n\n1. **Use hybrid search** - Combine vector + text for best results\n2. **Enable semantic ranking** - Improves relevance for natural language queries\n3. **Batch document uploads** - Use `uploadDocuments` with arrays, not single docs\n4. **Use filters for security** - Implement document-level security with filters\n5. **Index incrementally** - Use `mergeOrUploadDocuments` for updates\n6. **Monitor query performance** - Use `includeTotalCount: true` sparingly in production\n\n## When to Use\nThis skill is applicable to execute the workflow or actions described in the overview.",
  "applicable_domains": [
    "devops"
  ],
  "category": "devops",
  "invocation": [
    "/azure-search-documents-ts"
  ],
  "authored_by": "claudeskills.in community",
  "source_url": "https://claudeskills.in/skill/azure-search-documents-ts",
  "provenance": {
    "source": "claudeskills.in",
    "source_url": "https://claudeskills.in/skill/azure-search-documents-ts",
    "license": "unknown",
    "imported_at": "2026-09-03",
    "notes": "Aggregated by claudeskills.in from community GitHub lists."
  },
  "tags": [
    "claudeskills",
    "devops"
  ],
  "lifecycle": "draft"
}