Azure AI Search

Azure AI Search combines a Lucene-style inverted index and an HNSW vector index behind one API. Below the feature list and SDK examples, this page adds the ingestion and query architecture, guidance on when to use it instead of other vector stores, and the configuration mistakes that most often hurt RAG quality.

Azure AI Search

Azure AI Search (formerly Azure Cognitive Search) is Microsoft's managed search service and the default retrieval layer behind Azure OpenAI's "On Your Data" and AI Foundry RAG workflows. It supports full-text (BM25), vector, semantic reranking, and hybrid search in a single index, with built-in skillsets that call other Azure AI services (OCR, language, vision) during ingestion.


Key Features:


Index Schema Essentials:


Examples

1. Create an Index with Text + Vector Fields


from azure.search.documents.indexes import SearchIndexClient
from azure.search.documents.indexes.models import (
    SearchIndex, SearchField, SearchFieldDataType, SimpleField, SearchableField,
    VectorSearch, HnswAlgorithmConfiguration, VectorSearchProfile,
    SemanticConfiguration, SemanticField, SemanticPrioritizedFields, SemanticSearch,
)
from azure.core.credentials import AzureKeyCredential

client = SearchIndexClient("https://myco-search.search.windows.net", AzureKeyCredential("<key>"))

index = SearchIndex(
    name="hr-policies",
    fields=[
        SimpleField(name="id", type=SearchFieldDataType.String, key=True),
        SearchableField(name="title", type=SearchFieldDataType.String),
        SearchableField(name="content", type=SearchFieldDataType.String, analyzer_name="en.microsoft"),
        SearchField(
            name="content_vector",
            type=SearchFieldDataType.Collection(SearchFieldDataType.Single),
            searchable=True,
            vector_search_dimensions=1536,
            vector_search_profile_name="hnsw-default",
        ),
    ],
    vector_search=VectorSearch(
        algorithms=[HnswAlgorithmConfiguration(name="hnsw")],
        profiles=[VectorSearchProfile(name="hnsw-default", algorithm_configuration_name="hnsw")],
    ),
    semantic_search=SemanticSearch(configurations=[
        SemanticConfiguration(
            name="default",
            prioritized_fields=SemanticPrioritizedFields(
                title_field=SemanticField(field_name="title"),
                content_fields=[SemanticField(field_name="content")],
            ),
        )
    ]),
)
client.create_or_update_index(index)
  

2. Hybrid Search with Semantic Reranking


from azure.search.documents import SearchClient
from azure.search.documents.models import VectorizedQuery
from openai import AzureOpenAI

aoai = AzureOpenAI(azure_endpoint="...", api_key="...", api_version="2024-10-21")

def embed(text: str) -> list[float]:
    return aoai.embeddings.create(model="embedding-3-large-prod", input=[text]).data[0].embedding

search = SearchClient("https://myco-search.search.windows.net", "hr-policies", AzureKeyCredential("<key>"))

results = search.search(
    search_text="parental leave for new parents",      # BM25 side
    vector_queries=[VectorizedQuery(                   # vector side
        vector=embed("parental leave for new parents"),
        k_nearest_neighbors=50,
        fields="content_vector",
    )],
    query_type="semantic",                             # turns on semantic reranker
    semantic_configuration_name="default",
    top=5,
    select=["id", "title", "content"],
)

for r in results:
    print(f"{r['@search.reranker_score']:.3f}  {r['title']}")
  

3. Integrated Vectorization — Index from Blob Storage, No Pipeline Code

Point an indexer at a data source, attach a skillset that chunks + embeds, and Azure AI Search handles ingestion end-to-end.


{
  "name": "hr-skillset",
  "skills": [
    {
      "@odata.type": "#Microsoft.Skills.Text.SplitSkill",
      "textSplitMode": "pages",
      "maximumPageLength": 2000,
      "pageOverlapLength": 300,
      "inputs":  [{"name": "text", "source": "/document/content"}],
      "outputs": [{"name": "textItems", "targetName": "chunks"}]
    },
    {
      "@odata.type": "#Microsoft.Skills.Text.AzureOpenAIEmbeddingSkill",
      "resourceUri": "https://myco.openai.azure.com",
      "deploymentId": "embedding-3-large-prod",
      "modelName":    "text-embedding-3-large",
      "context": "/document/chunks/*",
      "inputs":  [{"name": "text", "source": "/document/chunks/*"}],
      "outputs": [{"name": "embedding", "targetName": "chunk_vector"}]
    }
  ]
}
  

4. Filtered Query for Document-Level Security


user_groups = ["hr-admin", "all-employees"]
filter_expr = " or ".join(f"acl_groups/any(g: g eq '{g}')" for g in user_groups)

results = search.search(
    search_text="termination policy",
    filter=filter_expr,
    top=10,
)
  

Common Use Cases:


1. Ingestion architecture

Azure AI Search ingestion architecture Blob / ADLS / SharePoint source documents Indexer scheduled crawl, change tracking Skillset OCR, chunking, embeddings Search index text fields, vectors, filters

There are two ways to get data in. The push model has your code call the index API with documents you have already chunked and embedded; it gives complete control and works with any source. The pull model uses an indexer, which connects to a supported data source on a schedule, tracks changes, cracks documents (PDF, Office, HTML), runs a skillset, and writes the enriched output to the index through field mappings. Integrated vectorization adds a text-split skill and an embedding skill so chunking and embedding happen inside the service, and attaches a vectorizer to the index so queries can be embedded server-side too.

2. Hybrid query pipeline

Hybrid query pipeline Query text + vector BM25 keyword top-k HNSW vector top-k RRF fusion merge ranks Semantic ranker rerank top 50

A hybrid request runs the keyword query against the inverted index with BM25 and the vector query against HNSW in parallel. Reciprocal rank fusion combines the two ranked lists using rank positions only, which avoids normalising incompatible BM25 and cosine scores. The optional semantic ranker then rescores the top 50 fused results with a cross-encoder and can return extractive captions and answers. Filters on filterable fields (tenant, ACL groups, dates) are applied in the same request; for vectors you choose pre-filtering or post-filtering.

3. When to use it

OptionBest whenTrade-off
Azure AI SearchAzure-centric stack, need hybrid + semantic ranking, ACL filters, managed indexersPriced by provisioned search units; less control over ANN internals
pgvector / PostgreSQLData already relational, moderate scaleBuild keyword and hybrid ranking yourself
Elasticsearch / OpenSearchExisting Elastic estate, heavy log or keyword workloadsSelf-manage or separate managed offering
Dedicated vector DBVery large vector-only workloadsWeaker full-text search

4. Pitfalls