All skills
microsoft avatar

/azure-search-documents-ts

@338b73f
by microsoftmicrosoft/skills3.1k stars
351

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.

Use this Skill: https://skilld.dev/gh/microsoft/skills/azure-search-documents-ts

This session only. Nothing lands on disk.

referencesvector-search.md

≈2.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

@azure/search-documents - Vector Search Patterns

Reference documentation for vector search in the Azure AI Search TypeScript SDK.

Source: Azure SDK for JS - search-documents


Installation

npm install @azure/search-documents @azure/identity

Client Setup

import { SearchClient, SearchIndexClient } from "@azure/search-documents";
import { DefaultAzureCredential } from "@azure/identity";

const credential = new DefaultAzureCredential();
const endpoint = process.env["AZURE_SEARCH_ENDPOINT"]!;

// For searching
const searchClient = new SearchClient<MyDocument>(
  endpoint,
  "my-index",
  credential
);

// For index management
const indexClient = new SearchIndexClient(endpoint, credential);

VectorSearchOptions Interface

interface VectorSearchOptions {
  /** Vector queries to execute */
  queries?: VectorQuery[];
  
  /** Filter mode for vector queries */
  filterMode?: VectorFilterMode; // "preFilter" | "postFilter"
}

type VectorQuery = 
  | VectorizedQuery      // Pre-computed vector
  | VectorizableTextQuery // Text to be vectorized
  | VectorizableImageUrlQuery
  | VectorizableImageBinaryQuery;

Basic Vector Search

Search using a pre-computed embedding vector:

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

interface Product {
  id: string;
  name: string;
  description: string;
  descriptionVector: number[];
}

const searchClient = new SearchClient<Product>(endpoint, "products", credential);

// Your embedding (e.g., from OpenAI, Azure OpenAI, etc.)
const queryVector = await getEmbedding("comfortable running shoes");

const results = await searchClient.search("*", {
  vectorSearchOptions: {
    queries: [
      {
        kind: "vector",
        vector: queryVector,
        kNearestNeighborsCount: 10,
        fields: ["descriptionVector"],
      },
    ],
  },
  select: ["id", "name", "description"],
});

for await (const result of results.results) {
  console.log(`${result.document.name} (score: ${result.score})`);
}

Integrated Vectorization (Text)

Let Azure AI Search vectorize the query text automatically:

const results = await searchClient.search("*", {
  vectorSearchOptions: {
    queries: [
      {
        kind: "text",
        text: "comfortable running shoes",
        kNearestNeighborsCount: 10,
        fields: ["descriptionVector"],
      },
    ],
  },
});

Note: Requires a vectorizer configured on the index.


Hybrid Search (Text + Vector)

Combine keyword search with vector search for better results:

const results = await searchClient.search("running shoes", {
  // Keyword search component
  searchFields: ["name", "description"],
  
  // Vector search component
  vectorSearchOptions: {
    queries: [
      {
        kind: "text",
        text: "comfortable running shoes",
        kNearestNeighborsCount: 50,
        fields: ["descriptionVector"],
      },
    ],
  },
  
  // Return top 10 after RRF fusion
  top: 10,
  select: ["id", "name", "description"],
});

Multi-Vector Search

Search across multiple vector fields simultaneously:

const results = await searchClient.search("*", {
  vectorSearchOptions: {
    queries: [
      // Search title embeddings
      {
        kind: "text",
        text: "machine learning",
        kNearestNeighborsCount: 50,
        fields: ["titleVector"],
        weight: 2.0, // Boost title matches
      },
      // Search content embeddings
      {
        kind: "text",
        text: "machine learning",
        kNearestNeighborsCount: 50,
        fields: ["contentVector"],
        weight: 1.0,
      },
    ],
  },
  top: 10,
});

Vector Filtering

Pre-Filter (Default)

Apply filters before vector search - smaller search space, faster:

const results = await searchClient.search("*", {
  filter: "category eq 'Electronics' and price lt 500",
  vectorSearchOptions: {
    filterMode: "preFilter", // Default
    queries: [
      {
        kind: "text",
        text: "wireless headphones",
        kNearestNeighborsCount: 10,
        fields: ["descriptionVector"],
      },
    ],
  },
});

Post-Filter

Apply filters after vector search - ensures k results are found first:

const results = await searchClient.search("*", {
  filter: "category eq 'Electronics'",
  vectorSearchOptions: {
    filterMode: "postFilter",
    queries: [
      {
        kind: "text",
        text: "wireless headphones",
        kNearestNeighborsCount: 50, // Get more, then filter
        fields: ["descriptionVector"],
      },
    ],
  },
  top: 10,
});

Per-Query Filter Override

Apply different filters to different vector queries:

const results = await searchClient.search("*", {
  filter: "inStock eq true", // Global filter
  vectorSearchOptions: {
    queries: [
      {
        kind: "text",
        text: "premium headphones",
        kNearestNeighborsCount: 20,
        fields: ["descriptionVector"],
        filterOverride: "category eq 'Audio' and price gt 200", // Override for this query
      },
    ],
  },
});

Vector Thresholds

Set minimum similarity thresholds:

const results = await searchClient.search("*", {
  vectorSearchOptions: {
    queries: [
      {
        kind: "text",
        text: "wireless headphones",
        kNearestNeighborsCount: 50,
        fields: ["descriptionVector"],
        threshold: {
          kind: "vectorSimilarity",
          value: 0.8, // Only results with similarity >= 0.8
        },
      },
    ],
  },
});

Exhaustive Search

Force brute-force search instead of approximate (HNSW):

const results = await searchClient.search("*", {
  vectorSearchOptions: {
    queries: [
      {
        kind: "text",
        text: "specific product query",
        kNearestNeighborsCount: 10,
        fields: ["descriptionVector"],
        exhaustive: true, // Slower but more accurate
      },
    ],
  },
});

Index Configuration for Vector Search

Create an index with vector search capabilities:

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

const indexClient = new SearchIndexClient(endpoint, credential);

const index: SearchIndex = {
  name: "products",
  fields: [
    { name: "id", type: "Edm.String", key: true },
    { name: "name", type: "Edm.String", searchable: true },
    { name: "description", type: "Edm.String", searchable: true },
    { name: "category", type: "Edm.String", filterable: true, facetable: true },
    { name: "price", type: "Edm.Double", filterable: true, sortable: true },
    {
      name: "descriptionVector",
      type: "Collection(Edm.Single)",
      searchable: true,
      vectorSearchDimensions: 1536,
      vectorSearchProfileName: "vector-profile",
    },
  ],
  vectorSearch: {
    algorithms: [
      {
        name: "hnsw-algorithm",
        kind: "hnsw",
        parameters: {
          m: 4,
          efConstruction: 400,
          efSearch: 500,
          metric: "cosine",
        },
      },
    ],
    profiles: [
      {
        name: "vector-profile",
        algorithmConfigurationName: "hnsw-algorithm",
        vectorizerName: "openai-vectorizer", // Optional: for integrated vectorization
      },
    ],
    vectorizers: [
      {
        name: "openai-vectorizer",
        kind: "azureOpenAI",
        azureOpenAIParameters: {
          resourceUri: process.env["AZURE_OPENAI_ENDPOINT"]!,
          deploymentId: "text-embedding-ada-002",
          modelName: "text-embedding-ada-002",
        },
      },
    ],
  },
};

await indexClient.createOrUpdateIndex(index);

Complete Hybrid Search Example

import { SearchClient } from "@azure/search-documents";
import { DefaultAzureCredential } from "@azure/identity";

interface Product {
  id: string;
  name: string;
  description: string;
  category: string;
  price: number;
}

async function hybridSearch(query: string, category?: string) {
  const client = new SearchClient<Product>(
    process.env["AZURE_SEARCH_ENDPOINT"]!,
    "products",
    new DefaultAzureCredential()
  );

  const filter = category ? `category eq '${category}'` : undefined;

  const results = await client.search(query, {
    filter,
    searchFields: ["name", "description"],
    vectorSearchOptions: {
      queries: [
        {
          kind: "text",
          text: query,
          kNearestNeighborsCount: 50,
          fields: ["descriptionVector"],
        },
      ],
    },
    top: 10,
    select: ["id", "name", "description", "category", "price"],
  });

  const items: Array<{ document: Product; score: number }> = [];
  
  for await (const result of results.results) {
    items.push({
      document: result.document,
      score: result.score ?? 0,
    });
  }

  return items;
}

// Usage
const results = await hybridSearch("wireless noise canceling", "Electronics");
results.forEach((r) => {
  console.log(`${r.document.name}: $${r.document.price} (score: ${r.score})`);
});

Best Practices

  1. Use hybrid search - Combining keyword + vector typically outperforms either alone
  2. Tune kNearestNeighborsCount - Higher values increase recall but slow down search
  3. Use pre-filtering - When filter selectivity is high (filters out most documents)
  4. Use post-filtering - When you need exactly k vector matches, then filter
  5. Set appropriate thresholds - Filter out low-quality matches
  6. Weight vector queries - Boost more relevant vector fields
  7. Monitor index metrics - Track search latency and recall

See Also

Source: SKILL.md on GitHub

2 warnings15d4 checks · Risk SAFE
  • Gen Agent Trust Hub15d

    This skill provides a comprehensive interface for integrating Azure AI Search into applications. It follows security best practices by utilizing official Microsoft SDKs and recommended authentication patterns like Managed Identities and DefaultAzureCredential.

  • Socket15d

    No alerts

  • Snyk15d

    Risk: MEDIUM · 1 issue

  • Runlayer7mo

    4/4 files flagged

Signed by skilld at 338b73f. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 5 months ago
Other metadata
metadata
{
  "author": "Microsoft",
  "version": "1.0.0",
  "package": "@azure/search-documents"
}

README badge

README badge for microsoft/skills/azure-search-documents-ts